mirror of
https://github.com/zyantific/zasm
synced 2026-06-08 18:40:54 +00:00
Merge pull request #123 from zyantific/error-handling
Improve error handling
This commit is contained in:
@@ -67,6 +67,7 @@ endif()
|
||||
|
||||
# Target: zasm
|
||||
set(zasm_SOURCES
|
||||
"src/zasm/src/core/error.cpp"
|
||||
"src/zasm/src/core/filestream.cpp"
|
||||
"src/zasm/src/core/memorystream.cpp"
|
||||
"src/zasm/src/decoder/decoder.cpp"
|
||||
@@ -165,6 +166,7 @@ if(ZASM_BUILD_TESTS OR CMKR_ROOT_PROJECT) # tests
|
||||
"src/tests/main.cpp"
|
||||
"src/tests/tests/tests.assembler.cpp"
|
||||
"src/tests/tests/tests.decoder.cpp"
|
||||
"src/tests/tests/tests.error.cpp"
|
||||
"src/tests/tests/tests.externals.cpp"
|
||||
"src/tests/tests/tests.formatter.cpp"
|
||||
"src/tests/tests/tests.imports.cpp"
|
||||
|
||||
@@ -28,7 +28,7 @@ int main()
|
||||
Serializer serializer{};
|
||||
|
||||
auto res = serializer.serialize(program, 0x00400000);
|
||||
assert(res == Error::None);
|
||||
assert(res == ErrorCode::None);
|
||||
|
||||
std::cout << examples::utils::getDisassemblyDump(serializer, program.getMode()) << "\n";
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ int main()
|
||||
Serializer serializer{};
|
||||
|
||||
auto res = serializer.serialize(program, 0x00400000);
|
||||
assert(res == Error::None);
|
||||
assert(res == ErrorCode::None);
|
||||
|
||||
std::cout << examples::utils::getDisassemblyDump(serializer, program.getMode()) << "\n";
|
||||
}
|
||||
|
||||
@@ -127,9 +127,9 @@ int main()
|
||||
|
||||
// Serialize program.
|
||||
Serializer serializer;
|
||||
if (auto err = serializer.serialize(program, reinterpret_cast<int64_t>(pCodePage)); err != zasm::Error::None)
|
||||
if (auto err = serializer.serialize(program, reinterpret_cast<int64_t>(pCodePage)); err != zasm::ErrorCode::None)
|
||||
{
|
||||
std::cout << "Serialization failure: " << zasm::getErrorName(err) << "\n";
|
||||
std::cout << "Serialization failure: " << err.getErrorName() << "\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace zasm::examples::utils
|
||||
auto res = decoder.decode(sectBuf + sectOffset, sectLen - sectOffset, curAddress);
|
||||
if (!res.hasValue())
|
||||
{
|
||||
std::cout << "Decoder Error: " << zasm::getErrorName(res.error()) << std::endl;
|
||||
std::cout << "Decoder Error: " << res.error().getErrorName() << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,16 +33,16 @@ int main()
|
||||
const auto decoderRes = decoder.decode(code.data() + bytesDecoded, code.size() - bytesDecoded, curAddress);
|
||||
if (!decoderRes)
|
||||
{
|
||||
std::cout << "Failed to decode at " << std::hex << curAddress << ", " << getErrorName(decoderRes.error()) << "\n";
|
||||
std::cout << "Failed to decode at " << std::hex << curAddress << ", " << decoderRes.error().getErrorName() << "\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
const auto& instrInfo = *decoderRes;
|
||||
|
||||
const auto instr = instrInfo.getInstruction();
|
||||
if (auto res = assembler.emit(instr); res != zasm::Error::None)
|
||||
if (auto res = assembler.emit(instr); res != zasm::ErrorCode::None)
|
||||
{
|
||||
std::cout << "Failed to emit instruction " << std::hex << curAddress << ", " << getErrorName(res) << "\n";
|
||||
std::cout << "Failed to emit instruction " << std::hex << curAddress << ", " << res.getErrorName() << "\n";
|
||||
}
|
||||
|
||||
bytesDecoded += instrInfo.getLength();
|
||||
|
||||
@@ -51,7 +51,7 @@ int main()
|
||||
Serializer serializer{};
|
||||
|
||||
auto res = serializer.serialize(program, 0x00400000);
|
||||
assert(res == Error::None);
|
||||
assert(res == ErrorCode::None);
|
||||
|
||||
std::cout << examples::utils::getDisassemblyDump(serializer, program.getMode()) << "\n";
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
namespace zasm
|
||||
{
|
||||
enum class Error : std::uint32_t
|
||||
enum class ErrorCode : std::uint32_t
|
||||
{
|
||||
None = 0,
|
||||
// Generic.
|
||||
@@ -28,47 +28,81 @@ namespace zasm
|
||||
// Decoder.
|
||||
InvalidInstruction,
|
||||
OutOfBounds,
|
||||
InstructionTooLong,
|
||||
// Encoder.
|
||||
ImpossibleInstruction,
|
||||
AddressOutOfRange,
|
||||
// Serialization.
|
||||
EmptyState,
|
||||
ImpossibleRelocation,
|
||||
};
|
||||
|
||||
static constexpr const char* getErrorName(Error err) noexcept
|
||||
/// <summary>
|
||||
/// The Error class represents an error code and can have additionally a message attached.
|
||||
/// If the object is constructed with an error message additional memory will be allocated.
|
||||
/// If the object is constructed only with an error code there will be no extra allocation.
|
||||
/// </summary>
|
||||
class Error
|
||||
{
|
||||
#define ERROR_STRING(e) \
|
||||
case e: \
|
||||
return #e
|
||||
std::uintptr_t _data{};
|
||||
|
||||
switch (err)
|
||||
{
|
||||
ERROR_STRING(Error::None);
|
||||
ERROR_STRING(Error::InvalidMode);
|
||||
ERROR_STRING(Error::NotInitialized);
|
||||
ERROR_STRING(Error::InvalidOperation);
|
||||
ERROR_STRING(Error::InvalidParameter);
|
||||
ERROR_STRING(Error::FileNotFound);
|
||||
ERROR_STRING(Error::AccessDenied);
|
||||
ERROR_STRING(Error::OutOfMemory);
|
||||
ERROR_STRING(Error::LabelNotFound);
|
||||
ERROR_STRING(Error::UnresolvedLabel);
|
||||
ERROR_STRING(Error::InvalidLabel);
|
||||
ERROR_STRING(Error::LabelAlreadyBound);
|
||||
ERROR_STRING(Error::SectionNotFound);
|
||||
ERROR_STRING(Error::SectionAlreadyBound);
|
||||
ERROR_STRING(Error::SignatureMismatch);
|
||||
ERROR_STRING(Error::InvalidInstruction);
|
||||
ERROR_STRING(Error::OutOfBounds);
|
||||
ERROR_STRING(Error::ImpossibleInstruction);
|
||||
ERROR_STRING(Error::EmptyState);
|
||||
ERROR_STRING(Error::ImpossibleRelocation);
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
#undef ERROR_STRING
|
||||
return nullptr;
|
||||
}
|
||||
public:
|
||||
constexpr Error() noexcept = default;
|
||||
Error(const Error& other);
|
||||
Error(Error&& other) noexcept;
|
||||
|
||||
/// <summary>
|
||||
/// Construct an Error object with the given error code.
|
||||
/// </summary>
|
||||
/// <param name="code">Error Code</param>
|
||||
Error(ErrorCode code) noexcept;
|
||||
|
||||
/// <summary>
|
||||
/// Construct an Error object with the given error code and an additional message.
|
||||
/// The message will be copied so it is safe to pass a temporary string.
|
||||
/// </summary>
|
||||
/// <param name="code">Error Code</param>
|
||||
/// <param name="message">Additional information</param>
|
||||
Error(ErrorCode code, const char* message);
|
||||
|
||||
~Error() noexcept;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the assigned error code.
|
||||
/// </summary>
|
||||
/// <returns>Error code</returns>
|
||||
ErrorCode getCode() const noexcept;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the error code name as a string.
|
||||
/// The return value is never nullptr.
|
||||
/// </summary>
|
||||
/// <returns>Error name</returns>
|
||||
const char* getErrorName() const noexcept;
|
||||
|
||||
/// <summary>
|
||||
/// Get the error message if it was set. If the object was constructed without a message
|
||||
/// this function will translate the error code into a generic message.
|
||||
/// The return value is never nullptr.
|
||||
/// </summary>
|
||||
/// <returns>Error message</returns>
|
||||
const char* getErrorMessage() const noexcept;
|
||||
|
||||
/// <summary>
|
||||
/// Clears the error object which means that the error code will be set to ErrorCode::None.
|
||||
/// If the object has an additional message it will be deallocated.
|
||||
/// </summary>
|
||||
void clear();
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the error object is empty.
|
||||
/// </summary>
|
||||
bool empty() const noexcept;
|
||||
|
||||
bool operator==(ErrorCode code) const noexcept;
|
||||
bool operator!=(ErrorCode code) const noexcept;
|
||||
Error& operator=(Error&& other) noexcept;
|
||||
Error& operator=(const Error& other) noexcept;
|
||||
};
|
||||
|
||||
} // namespace zasm
|
||||
|
||||
@@ -10,10 +10,15 @@ namespace zasm
|
||||
// Internal wrapper type for unexpected.
|
||||
template<typename T> struct Unexpected
|
||||
{
|
||||
const T failure;
|
||||
T failure;
|
||||
|
||||
constexpr Unexpected(const T& val) noexcept
|
||||
: failure{ val }
|
||||
constexpr Unexpected(T&& arg) noexcept
|
||||
: failure{ std::move(arg) }
|
||||
{
|
||||
}
|
||||
|
||||
constexpr Unexpected(const T& arg) noexcept
|
||||
: failure{ arg }
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
@@ -129,48 +129,48 @@ namespace zasm
|
||||
const auto entryCount = static_cast<std::uint32_t>(_entries.size());
|
||||
if (auto len = stream.write(&entryCount, sizeof(entryCount)); len == 0)
|
||||
{
|
||||
return Error::InvalidParameter;
|
||||
return ErrorCode::InvalidParameter;
|
||||
}
|
||||
|
||||
for (const auto& entry : _entries)
|
||||
{
|
||||
if (auto len = stream.write(entry.hash); len == 0)
|
||||
{
|
||||
return Error::InvalidParameter;
|
||||
return ErrorCode::InvalidParameter;
|
||||
}
|
||||
if (auto len = stream.write(entry.offset); len == 0)
|
||||
{
|
||||
return Error::InvalidParameter;
|
||||
return ErrorCode::InvalidParameter;
|
||||
}
|
||||
if (auto len = stream.write(entry.len); len == 0)
|
||||
{
|
||||
return Error::InvalidParameter;
|
||||
return ErrorCode::InvalidParameter;
|
||||
}
|
||||
if (auto len = stream.write(entry.capacity); len == 0)
|
||||
{
|
||||
return Error::InvalidParameter;
|
||||
return ErrorCode::InvalidParameter;
|
||||
}
|
||||
if (auto len = stream.write(entry.refCount); len == 0)
|
||||
{
|
||||
return Error::InvalidParameter;
|
||||
return ErrorCode::InvalidParameter;
|
||||
}
|
||||
}
|
||||
|
||||
const auto dataSize = static_cast<std::uint32_t>(_data.size());
|
||||
if (auto len = stream.write(dataSize); len == 0)
|
||||
{
|
||||
return Error::InvalidParameter;
|
||||
return ErrorCode::InvalidParameter;
|
||||
}
|
||||
|
||||
if (dataSize > 0)
|
||||
{
|
||||
if (auto len = stream.write(_data.data(), dataSize); len == 0)
|
||||
{
|
||||
return Error::InvalidParameter;
|
||||
return ErrorCode::InvalidParameter;
|
||||
}
|
||||
}
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
Error load(IStream& stream)
|
||||
@@ -180,7 +180,7 @@ namespace zasm
|
||||
std::uint32_t entryCount{};
|
||||
if (auto len = stream.read(&entryCount, sizeof(entryCount)); len == 0)
|
||||
{
|
||||
return Error::InvalidParameter;
|
||||
return ErrorCode::InvalidParameter;
|
||||
}
|
||||
|
||||
std::vector<Entry> loadedEntries;
|
||||
@@ -189,30 +189,30 @@ namespace zasm
|
||||
{
|
||||
if (auto len = stream.read(entry.hash); len == 0)
|
||||
{
|
||||
return Error::InvalidParameter;
|
||||
return ErrorCode::InvalidParameter;
|
||||
}
|
||||
if (auto len = stream.read(entry.offset); len == 0)
|
||||
{
|
||||
return Error::InvalidParameter;
|
||||
return ErrorCode::InvalidParameter;
|
||||
}
|
||||
if (auto len = stream.read(entry.len); len == 0)
|
||||
{
|
||||
return Error::InvalidParameter;
|
||||
return ErrorCode::InvalidParameter;
|
||||
}
|
||||
if (auto len = stream.read(entry.capacity); len == 0)
|
||||
{
|
||||
return Error::InvalidParameter;
|
||||
return ErrorCode::InvalidParameter;
|
||||
}
|
||||
if (auto len = stream.read(entry.refCount); len == 0)
|
||||
{
|
||||
return Error::InvalidParameter;
|
||||
return ErrorCode::InvalidParameter;
|
||||
}
|
||||
}
|
||||
|
||||
std::uint32_t dataSize{};
|
||||
if (auto len = stream.read(&dataSize, sizeof(dataSize)); len == 0)
|
||||
{
|
||||
return Error::InvalidParameter;
|
||||
return ErrorCode::InvalidParameter;
|
||||
}
|
||||
|
||||
std::vector<char> loadedData;
|
||||
@@ -221,14 +221,14 @@ namespace zasm
|
||||
loadedData.resize(dataSize);
|
||||
if (auto len = stream.read(loadedData.data(), dataSize); len == 0)
|
||||
{
|
||||
return Error::InvalidParameter;
|
||||
return ErrorCode::InvalidParameter;
|
||||
}
|
||||
}
|
||||
|
||||
_entries = std::move(loadedEntries);
|
||||
_data = std::move(loadedData);
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -18,6 +18,10 @@ namespace zasm
|
||||
|
||||
Result decode(const void* data, std::size_t len, std::uint64_t address) noexcept;
|
||||
|
||||
MachineMode getMode() const;
|
||||
|
||||
const Error& getLastError() const;
|
||||
|
||||
private:
|
||||
ZydisDecoder _decoder{};
|
||||
MachineMode _mode{};
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace zasm::formatter
|
||||
/// </summary>
|
||||
/// <param name="program">The program to print as text</param>
|
||||
/// <param name="options">Format options</param>
|
||||
std::string toString(Program& program, Options options = kDefaultOptions);
|
||||
std::string toString(const Program& program, Options options = kDefaultOptions);
|
||||
|
||||
/// <summary>
|
||||
/// Formats a single node and results the text.
|
||||
@@ -44,7 +44,7 @@ namespace zasm::formatter
|
||||
/// <param name="program">The program to print as text</param>
|
||||
/// <param name="node">Formats only the specified node</param>
|
||||
/// <param name="options">Format options</param>
|
||||
std::string toString(Program& program, const Node* node, Options options = kDefaultOptions);
|
||||
std::string toString(const Program& program, const Node* node, Options options = kDefaultOptions);
|
||||
|
||||
/// <summary>
|
||||
/// Formats the specified range, 'to' is not inclusive.
|
||||
@@ -53,7 +53,7 @@ namespace zasm::formatter
|
||||
/// <param name="nodeFrom">First node</param>
|
||||
/// <param name="nodeTo">Last node</param>
|
||||
/// <param name="options">Format options</param>
|
||||
std::string toString(Program& program, const Node* nodeFrom, const Node* nodeTo, Options options = kDefaultOptions);
|
||||
std::string toString(const Program& program, const Node* nodeFrom, const Node* nodeTo, Options options = kDefaultOptions);
|
||||
|
||||
/// <summary>
|
||||
/// Formats a single instruction and results the text.
|
||||
@@ -61,7 +61,7 @@ namespace zasm::formatter
|
||||
/// <param name="program">The program to print as text</param>
|
||||
/// <param name="instr">Instruction to format</param>
|
||||
/// <param name="options">Format options</param>
|
||||
std::string toString(Program& program, const Instruction* instr, Options options = kDefaultOptions);
|
||||
std::string toString(const Program& program, const Instruction* instr, Options options = kDefaultOptions);
|
||||
|
||||
/// <summary>
|
||||
/// Formats a single instruction and results the text.
|
||||
|
||||
@@ -2082,6 +2082,10 @@ namespace zasm::x86
|
||||
{
|
||||
return emit(x86::Mnemonic::Jecxz, a);
|
||||
}
|
||||
inline Error jecxz(const Label& a)
|
||||
{
|
||||
return emit(x86::Mnemonic::Jecxz, a);
|
||||
}
|
||||
inline Error jknzd(const Mask& a, const Imm& b)
|
||||
{
|
||||
return emit(x86::Mnemonic::Jknzd, a, b);
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace zasm::tests
|
||||
|
||||
auto label01 = assembler.createLabel();
|
||||
ASSERT_EQ(label01.isValid(), true);
|
||||
ASSERT_EQ(assembler.bind(label01), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
}
|
||||
|
||||
TEST(AssemblerTests, TestDoubleBindLabel)
|
||||
@@ -22,8 +22,8 @@ namespace zasm::tests
|
||||
|
||||
auto label01 = assembler.createLabel();
|
||||
ASSERT_EQ(label01.isValid(), true);
|
||||
ASSERT_EQ(assembler.bind(label01), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), Error::LabelAlreadyBound);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::LabelAlreadyBound);
|
||||
}
|
||||
|
||||
TEST(AssemblerTests, TestBindInvalidLabel)
|
||||
@@ -32,9 +32,9 @@ namespace zasm::tests
|
||||
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
zasm::Label label01;
|
||||
Label label01;
|
||||
ASSERT_EQ(label01.isValid(), false);
|
||||
ASSERT_EQ(assembler.bind(label01), Error::InvalidLabel);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::InvalidLabel);
|
||||
}
|
||||
|
||||
TEST(AssemblerTests, TestEmitDirectMov)
|
||||
@@ -43,7 +43,7 @@ namespace zasm::tests
|
||||
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
ASSERT_EQ(assembler.emit(x86::Mnemonic::Mov, x86::rax, Imm(01)), Error::None);
|
||||
ASSERT_EQ(assembler.emit(x86::Mnemonic::Mov, x86::rax, Imm(01)), ErrorCode::None);
|
||||
}
|
||||
|
||||
TEST(AssemblerTests, TestRemoveCursorNode)
|
||||
@@ -52,11 +52,11 @@ namespace zasm::tests
|
||||
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
ASSERT_EQ(assembler.mov(x86::rax, x86::rax), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::rax, x86::rax), ErrorCode::None);
|
||||
auto* nodeA = assembler.getCursor();
|
||||
ASSERT_EQ(assembler.mov(x86::rdx, x86::rdx), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::rdx, x86::rdx), ErrorCode::None);
|
||||
auto* nodeB = assembler.getCursor();
|
||||
ASSERT_EQ(assembler.mov(x86::rbx, x86::rbx), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::rbx, x86::rbx), ErrorCode::None);
|
||||
auto* nodeC = assembler.getCursor();
|
||||
|
||||
program.destroy(nodeC);
|
||||
|
||||
@@ -22,10 +22,10 @@ namespace zasm::tests
|
||||
ASSERT_EQ(decoded->getMnemonic(), x86::Mnemonic::Mov);
|
||||
ASSERT_EQ(decoded->getOperandCount(), 2);
|
||||
|
||||
ASSERT_EQ(assembler.emit(decoded.value().getInstruction()), Error::None);
|
||||
ASSERT_EQ(assembler.emit(decoded.value().getInstruction()), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x00400000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x00400000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 5> expected = {
|
||||
0xB8, 0x01, 0x00, 0x00, 0x00,
|
||||
@@ -60,10 +60,10 @@ namespace zasm::tests
|
||||
ASSERT_EQ(decoded->getOperand<Mem>(0).getBase(), x86::rip);
|
||||
ASSERT_EQ(decoded->getOperand<Mem>(0).getDisplacement(), 0x00007FF8833E0679);
|
||||
|
||||
ASSERT_EQ(assembler.emit(decoded.value().getInstruction()), Error::None);
|
||||
ASSERT_EQ(assembler.emit(decoded.value().getInstruction()), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x00007FF8833DF000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x00007FF8833DF000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 6> expected = {
|
||||
0xFF, 0x15, 0x73, 0x16, 0x00, 0x00,
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
#include <chrono>
|
||||
#include <gtest/gtest.h>
|
||||
#include <zasm/core/errors.hpp>
|
||||
|
||||
namespace zasm::tests
|
||||
{
|
||||
TEST(ErrorTests, TestBasic)
|
||||
{
|
||||
Error error(ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error, ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getCode(), ErrorCode::InvalidMode);
|
||||
}
|
||||
|
||||
TEST(ErrorTests, TestExt)
|
||||
{
|
||||
Error error(ErrorCode::InvalidMode, "test message");
|
||||
ASSERT_EQ(error, ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getCode(), ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getErrorMessage(), std::string("test message"));
|
||||
}
|
||||
|
||||
TEST(ErrorTests, TestExtClear)
|
||||
{
|
||||
Error error(ErrorCode::InvalidMode, "test message");
|
||||
ASSERT_EQ(error, ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getCode(), ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getErrorMessage(), std::string("test message"));
|
||||
|
||||
error.clear();
|
||||
ASSERT_TRUE(error.empty());
|
||||
ASSERT_EQ(error, ErrorCode::None);
|
||||
}
|
||||
|
||||
TEST(ErrorTests, TestCopy1)
|
||||
{
|
||||
Error error(ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error, ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getCode(), ErrorCode::InvalidMode);
|
||||
|
||||
Error error2(error);
|
||||
ASSERT_EQ(error2, ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error2.getCode(), ErrorCode::InvalidMode);
|
||||
}
|
||||
|
||||
TEST(ErrorTests, TestCopy2)
|
||||
{
|
||||
Error error(ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error, ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getCode(), ErrorCode::InvalidMode);
|
||||
|
||||
Error error2;
|
||||
error2 = error;
|
||||
ASSERT_EQ(error2, ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error2.getCode(), ErrorCode::InvalidMode);
|
||||
}
|
||||
|
||||
TEST(ErrorTests, TestCopyExt1)
|
||||
{
|
||||
Error error(ErrorCode::InvalidMode, "test message");
|
||||
ASSERT_EQ(error, ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getCode(), ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getErrorMessage(), std::string("test message"));
|
||||
|
||||
Error error2(error);
|
||||
ASSERT_EQ(error2, ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error2.getCode(), ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error2.getErrorMessage(), std::string("test message"));
|
||||
}
|
||||
|
||||
TEST(ErrorTests, TestCopyExt2)
|
||||
{
|
||||
Error error(ErrorCode::InvalidMode, "test message");
|
||||
ASSERT_EQ(error, ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getCode(), ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getErrorMessage(), std::string("test message"));
|
||||
|
||||
Error error2;
|
||||
error2 = error;
|
||||
ASSERT_EQ(error2, ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error2.getCode(), ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error2.getErrorMessage(), std::string("test message"));
|
||||
}
|
||||
|
||||
TEST(ErrorTests, TestMoveExt1)
|
||||
{
|
||||
Error error(ErrorCode::InvalidMode, "test message");
|
||||
ASSERT_EQ(error, ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getCode(), ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getErrorMessage(), std::string("test message"));
|
||||
|
||||
Error error2(std::move(error));
|
||||
ASSERT_EQ(error2, ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error2.getCode(), ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error2.getErrorMessage(), std::string("test message"));
|
||||
|
||||
ASSERT_TRUE(error.empty());
|
||||
}
|
||||
|
||||
TEST(ErrorTests, TestMoveExt2)
|
||||
{
|
||||
Error error(ErrorCode::InvalidMode, "test message");
|
||||
ASSERT_EQ(error, ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getCode(), ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getErrorMessage(), std::string("test message"));
|
||||
|
||||
Error error2;
|
||||
error2 = std::move(error);
|
||||
ASSERT_EQ(error2, ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error2.getCode(), ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error2.getErrorMessage(), std::string("test message"));
|
||||
|
||||
ASSERT_TRUE(error.empty());
|
||||
}
|
||||
|
||||
#if defined(_DEBUG) && 0
|
||||
// Leak Tests.
|
||||
// Disabled by default, this is a very crude way to test for memory leaks.
|
||||
// The process runs for 5 seconds and creates/destroys Error objects in where we can observe
|
||||
// if the memory usage is stable.
|
||||
|
||||
static constexpr auto kLeakTestDurationSecs = std::chrono::milliseconds(5000);
|
||||
|
||||
TEST(ErrorTests, TestLeak1)
|
||||
{
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
while (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start)
|
||||
< kLeakTestDurationSecs)
|
||||
{
|
||||
Error error(ErrorCode::InvalidMode, "test message");
|
||||
ASSERT_EQ(error, ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getCode(), ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getErrorMessage(), std::string("test message"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ErrorTests, TestLeak2)
|
||||
{
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
while (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start)
|
||||
< kLeakTestDurationSecs)
|
||||
{
|
||||
Error error(ErrorCode::InvalidMode, "test message");
|
||||
ASSERT_EQ(error, ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getCode(), ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getErrorMessage(), std::string("test message"));
|
||||
|
||||
Error error2(std::move(error));
|
||||
ASSERT_EQ(error2, ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error2.getCode(), ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error2.getErrorMessage(), std::string("test message"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ErrorTests, TestLeak3)
|
||||
{
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
while (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start)
|
||||
< kLeakTestDurationSecs)
|
||||
{
|
||||
Error error(ErrorCode::InvalidMode, "test message");
|
||||
ASSERT_EQ(error, ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getCode(), ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getErrorMessage(), std::string("test message"));
|
||||
|
||||
Error error2;
|
||||
error2 = std::move(error);
|
||||
ASSERT_EQ(error2, ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error2.getCode(), ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error2.getErrorMessage(), std::string("test message"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ErrorTests, TestLeak4)
|
||||
{
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
while (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start)
|
||||
< kLeakTestDurationSecs)
|
||||
{
|
||||
Error error(ErrorCode::InvalidMode, "test message");
|
||||
ASSERT_EQ(error, ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getCode(), ErrorCode::InvalidMode);
|
||||
ASSERT_EQ(error.getErrorMessage(), std::string("test message"));
|
||||
|
||||
error.clear();
|
||||
ASSERT_TRUE(error.empty());
|
||||
ASSERT_EQ(error, ErrorCode::None);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace zasm::tests
|
||||
@@ -13,10 +13,10 @@ namespace zasm::tests
|
||||
|
||||
auto externalLabel = program.createExternalLabel("external");
|
||||
|
||||
ASSERT_EQ(assembler.lea(x86::rax, x86::qword_ptr(x86::rip, externalLabel)), Error::None);
|
||||
ASSERT_EQ(assembler.lea(x86::rax, x86::qword_ptr(x86::rip, externalLabel)), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000400000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000400000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 7> expected = {
|
||||
0x48, 0x8D, 0x05, 0x00, 0x00, 0x00, 0x00,
|
||||
@@ -47,10 +47,10 @@ namespace zasm::tests
|
||||
|
||||
auto externalLabel = program.createExternalLabel("external");
|
||||
|
||||
ASSERT_EQ(assembler.lea(x86::rax, x86::qword_ptr(externalLabel)), Error::None);
|
||||
ASSERT_EQ(assembler.lea(x86::rax, x86::qword_ptr(externalLabel)), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000400000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000400000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 8> expected = { 0x48, 0x8d, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00 };
|
||||
ASSERT_EQ(serializer.getCodeSize(), expected.size());
|
||||
@@ -79,13 +79,13 @@ namespace zasm::tests
|
||||
|
||||
auto externalLabel = program.createExternalLabel("external");
|
||||
auto labelData = assembler.createLabel("EmbeddedLabelPos");
|
||||
ASSERT_EQ(assembler.lea(x86::rax, x86::qword_ptr(x86::rip, labelData)), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::rdx, x86::qword_ptr(x86::rax)), Error::None);
|
||||
ASSERT_EQ(assembler.bind(labelData), Error::None);
|
||||
ASSERT_EQ(assembler.embedLabel(externalLabel), Error::None);
|
||||
ASSERT_EQ(assembler.lea(x86::rax, x86::qword_ptr(x86::rip, labelData)), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.mov(x86::rdx, x86::qword_ptr(x86::rax)), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(labelData), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.embedLabel(externalLabel), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000400000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000400000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 18> expected = {
|
||||
0x48, 0x8D, 0x05, 0x03, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
@@ -116,13 +116,13 @@ namespace zasm::tests
|
||||
|
||||
auto externalLabel = program.createExternalLabel("external");
|
||||
auto labelData = assembler.createLabel("EmbeddedLabelPos");
|
||||
ASSERT_EQ(assembler.lea(x86::rax, x86::qword_ptr(labelData)), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::rdx, x86::qword_ptr(x86::rax)), Error::None);
|
||||
ASSERT_EQ(assembler.bind(labelData), Error::None);
|
||||
ASSERT_EQ(assembler.embedLabel(externalLabel), Error::None);
|
||||
ASSERT_EQ(assembler.lea(x86::rax, x86::qword_ptr(labelData)), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.mov(x86::rdx, x86::qword_ptr(x86::rax)), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(labelData), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.embedLabel(externalLabel), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000400000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000400000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 19> expected = { 0x48, 0x8d, 0x04, 0x25, 0x0b, 0x00, 0x40, 0x00, 0x48, 0x8b,
|
||||
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
@@ -153,13 +153,13 @@ namespace zasm::tests
|
||||
auto externalLabel = program.createExternalLabel("external");
|
||||
|
||||
auto labelData = assembler.createLabel("EmbeddedLabelPos");
|
||||
ASSERT_EQ(assembler.lea(x86::eax, x86::dword_ptr(labelData)), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::edx, x86::dword_ptr(x86::eax)), Error::None);
|
||||
ASSERT_EQ(assembler.bind(labelData), Error::None);
|
||||
ASSERT_EQ(assembler.embedLabel(externalLabel), Error::None);
|
||||
ASSERT_EQ(assembler.lea(x86::eax, x86::dword_ptr(labelData)), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.mov(x86::edx, x86::dword_ptr(x86::eax)), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(labelData), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.embedLabel(externalLabel), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000400000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000400000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 12> expected = {
|
||||
0x8D, 0x05, 0x08, 0x00, 0x40, 0x00, 0x8B, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
@@ -199,13 +199,13 @@ namespace zasm::tests
|
||||
|
||||
auto externalLabel = program.createExternalLabel("external");
|
||||
auto labelData = assembler.createLabel("EmbeddedLabelPos");
|
||||
ASSERT_EQ(assembler.lea(x86::eax, x86::dword_ptr(labelData)), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::edx, x86::dword_ptr(x86::eax)), Error::None);
|
||||
ASSERT_EQ(assembler.bind(labelData), Error::None);
|
||||
ASSERT_EQ(assembler.embedLabel(externalLabel), Error::None);
|
||||
ASSERT_EQ(assembler.lea(x86::eax, x86::dword_ptr(labelData)), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.mov(x86::edx, x86::dword_ptr(x86::eax)), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(labelData), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.embedLabel(externalLabel), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000400000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000400000), ErrorCode::None);
|
||||
|
||||
{
|
||||
const std::array<uint8_t, 12> expected = {
|
||||
@@ -238,7 +238,7 @@ namespace zasm::tests
|
||||
ASSERT_EQ(relocInfo->offset, 8);
|
||||
}
|
||||
|
||||
ASSERT_EQ(serializer.relocate(0x0000000000500000), Error::None);
|
||||
ASSERT_EQ(serializer.relocate(0x0000000000500000), ErrorCode::None);
|
||||
|
||||
{
|
||||
const std::array<uint8_t, 12> expected = {
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace zasm::tests
|
||||
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
ASSERT_EQ(assembler.mov(x86::eax, x86::edx), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, x86::edx), ErrorCode::None);
|
||||
|
||||
auto nodeStr = formatter::toString(program, program.getHead());
|
||||
ASSERT_EQ(nodeStr, std::string("mov eax, edx"));
|
||||
@@ -22,7 +22,7 @@ namespace zasm::tests
|
||||
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
ASSERT_EQ(assembler.lock().inc(x86::dword_ptr(x86::eax)), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.lock().inc(x86::dword_ptr(x86::eax)), ErrorCode::None);
|
||||
|
||||
auto nodeStr = formatter::toString(program, program.getHead());
|
||||
ASSERT_EQ(nodeStr, std::string("lock inc dword ptr ds:[eax]"));
|
||||
@@ -35,8 +35,8 @@ namespace zasm::tests
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
auto label = assembler.createLabel();
|
||||
ASSERT_EQ(assembler.lock().inc(x86::dword_ptr(label)), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.bind(label), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.lock().inc(x86::dword_ptr(label)), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label), ErrorCode::None);
|
||||
|
||||
auto nodeStr = formatter::toString(program, program.getHead());
|
||||
ASSERT_EQ(nodeStr, std::string("lock inc dword ptr ds:[L0]"));
|
||||
@@ -49,7 +49,7 @@ namespace zasm::tests
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
auto label = assembler.createLabel();
|
||||
ASSERT_EQ(assembler.mov(x86::eax, Imm(-1)), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, Imm(-1)), ErrorCode::None);
|
||||
|
||||
auto nodeStr = formatter::toString(program, program.getHead());
|
||||
ASSERT_EQ(nodeStr, std::string("mov eax, -1"));
|
||||
@@ -62,7 +62,7 @@ namespace zasm::tests
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
auto label = assembler.createLabel();
|
||||
ASSERT_EQ(assembler.mov(x86::eax, Imm(0x12345678)), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, Imm(0x12345678)), ErrorCode::None);
|
||||
|
||||
auto nodeStr = formatter::toString(program, program.getHead());
|
||||
ASSERT_EQ(nodeStr, std::string("mov eax, 305419896"));
|
||||
@@ -75,7 +75,7 @@ namespace zasm::tests
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
auto label = assembler.createLabel();
|
||||
ASSERT_EQ(assembler.mov(x86::eax, Imm(0x12345678)), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, Imm(0x12345678)), ErrorCode::None);
|
||||
|
||||
auto nodeStr = formatter::toString(program, program.getHead(), formatter::Options::HexImmediates);
|
||||
ASSERT_EQ(nodeStr, std::string("mov eax, 0x12345678"));
|
||||
@@ -88,7 +88,7 @@ namespace zasm::tests
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
auto label = assembler.createLabel();
|
||||
ASSERT_EQ(assembler.mov(x86::eax, x86::dword_ptr(x86::eax, 0x12345678)), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, x86::dword_ptr(x86::eax, 0x12345678)), ErrorCode::None);
|
||||
|
||||
auto nodeStr = formatter::toString(program, program.getHead(), formatter::Options::HexOffsets);
|
||||
ASSERT_EQ(nodeStr, std::string("mov eax, dword ptr ds:[eax+0x12345678]"));
|
||||
@@ -101,7 +101,7 @@ namespace zasm::tests
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
auto label = assembler.createLabel();
|
||||
ASSERT_EQ(assembler.mov(x86::eax, x86::dword_ptr(x86::eax, -0x12345678)), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, x86::dword_ptr(x86::eax, -0x12345678)), ErrorCode::None);
|
||||
|
||||
auto nodeStr = formatter::toString(program, program.getHead(), formatter::Options::HexOffsets);
|
||||
ASSERT_EQ(nodeStr, std::string("mov eax, dword ptr ds:[eax-0x12345678]"));
|
||||
@@ -116,12 +116,12 @@ namespace zasm::tests
|
||||
auto label01 = assembler.createLabel();
|
||||
auto label02 = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.jmp(label02), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.lock().inc(x86::dword_ptr(label01)), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.dd(0), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.bind(label02), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.nop(), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.jmp(label02), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.lock().inc(x86::dword_ptr(label01)), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.dd(0), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label02), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
|
||||
auto nodeStr = formatter::toString(program);
|
||||
ASSERT_EQ(nodeStr, std::string("jmp L1\nlock inc dword ptr ds:[L0]\nL0:\ndd 0x00000000\nL1:\nnop"));
|
||||
@@ -136,12 +136,12 @@ namespace zasm::tests
|
||||
auto label01 = assembler.createLabel("Label01");
|
||||
auto label02 = assembler.createLabel("Label02");
|
||||
|
||||
ASSERT_EQ(assembler.jmp(label02), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.lock().inc(x86::dword_ptr(label01)), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.dd(0), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.bind(label02), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.nop(), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.jmp(label02), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.lock().inc(x86::dword_ptr(label01)), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.dd(0), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label02), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
|
||||
auto nodeStr = formatter::toString(program);
|
||||
ASSERT_EQ(nodeStr, std::string("jmp Label02\nlock inc dword ptr ds:[Label01]\nLabel01:\ndd 0x00000000\nLabel02:\nnop"));
|
||||
|
||||
@@ -38,10 +38,10 @@ namespace zasm::tests
|
||||
const auto labelImpExitProcess = program.getOrCreateImportLabel("kernel32.dll", "ExitProcess");
|
||||
ASSERT_TRUE(labelImpExitProcess.isValid());
|
||||
|
||||
ASSERT_EQ(assembler.mov(x86::eax, x86::dword_ptr(labelImpExitProcess)), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, x86::dword_ptr(labelImpExitProcess)), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 5> expected = {
|
||||
0xA1, 0x00, 0x00, 0x00, 0x00,
|
||||
@@ -79,10 +79,10 @@ namespace zasm::tests
|
||||
const auto labelImpExitProcess = program.getOrCreateImportLabel("kernel32.dll", "ExitProcess");
|
||||
ASSERT_TRUE(labelImpExitProcess.isValid());
|
||||
|
||||
ASSERT_EQ(assembler.mov(x86::rax, x86::qword_ptr(x86::rip, labelImpExitProcess)), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::rax, x86::qword_ptr(x86::rip, labelImpExitProcess)), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 7> expected = {
|
||||
0x48, 0x8B, 0x05, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
@@ -16,13 +16,13 @@ namespace zasm::tests
|
||||
.addOperand(x86::eax) //
|
||||
.addOperand(zasm::Imm(1)); //
|
||||
|
||||
ASSERT_EQ(assembler.emit(instr), Error::None);
|
||||
ASSERT_EQ(assembler.emit(instr), ErrorCode::None);
|
||||
|
||||
const auto* instrNode = assembler.getCursor();
|
||||
ASSERT_NE(instrNode, nullptr);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x00400000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x00400000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 5> expected = {
|
||||
0xB8, 0x01, 0x00, 0x00, 0x00,
|
||||
@@ -43,7 +43,7 @@ namespace zasm::tests
|
||||
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
assembler.mov(x86::eax, zasm::Imm(2));
|
||||
assembler.mov(x86::eax, Imm(2));
|
||||
|
||||
auto* instrNode = assembler.getCursor();
|
||||
|
||||
@@ -51,10 +51,10 @@ namespace zasm::tests
|
||||
Instruction instr = assembler.getCursor()->get<Instruction>();
|
||||
|
||||
// Modify operand.
|
||||
instr.setOperand(1, zasm::Imm(1));
|
||||
instr.setOperand(1, Imm(1));
|
||||
|
||||
// Emit modified
|
||||
ASSERT_EQ(assembler.emit(instr), Error::None);
|
||||
ASSERT_EQ(assembler.emit(instr), ErrorCode::None);
|
||||
|
||||
// Remove original
|
||||
program.destroy(instrNode);
|
||||
@@ -63,7 +63,7 @@ namespace zasm::tests
|
||||
ASSERT_NE(instrNode, nullptr);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x00400000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x00400000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 5> expected = {
|
||||
0xB8, 0x01, 0x00, 0x00, 0x00,
|
||||
|
||||
@@ -18,10 +18,10 @@ namespace zasm::tests
|
||||
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
ASSERT_EQ(instrTest.emitter(assembler), Error::None) << instrTest.operation;
|
||||
ASSERT_EQ(instrTest.emitter(assembler), ErrorCode::None) << instrTest.operation;
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None) << instrTest.operation;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None) << instrTest.operation;
|
||||
|
||||
auto hexEncoded = hexEncode(serializer.getCode(), serializer.getCodeSize());
|
||||
ASSERT_EQ(std::string(instrTest.instrBytes), hexEncoded) << instrTest.operation;
|
||||
@@ -40,11 +40,11 @@ namespace zasm::tests
|
||||
|
||||
for (const auto& instrEntry : data::Instructions)
|
||||
{
|
||||
ASSERT_EQ(instrEntry.emitter(assembler), Error::None) << instrEntry.instrBytes << ", " << instrEntry.operation;
|
||||
ASSERT_EQ(instrEntry.emitter(assembler), ErrorCode::None) << instrEntry.instrBytes << ", " << instrEntry.operation;
|
||||
}
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const uint8_t* codeBuf = serializer.getCode();
|
||||
size_t offset = 0;
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace zasm::tests
|
||||
Program program(MachineMode::AMD64);
|
||||
|
||||
x86::Assembler assembler(program);
|
||||
ASSERT_EQ(instrTest.emitter(assembler), Error::None) << instrTest.operation;
|
||||
ASSERT_EQ(instrTest.emitter(assembler), ErrorCode::None) << instrTest.operation;
|
||||
|
||||
const auto* node = assembler.getCursor();
|
||||
ASSERT_NE(node, nullptr);
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace zasm::tests
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
ASSERT_EQ(assembler.mov(x86::eax, Imm(i)), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, Imm(i)), ErrorCode::None);
|
||||
}
|
||||
ASSERT_EQ(program.size(), 10);
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace zasm::tests
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
ASSERT_EQ(assembler.mov(x86::eax, Imm(i)), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, Imm(i)), ErrorCode::None);
|
||||
}
|
||||
ASSERT_EQ(program.size(), 10);
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace zasm::tests
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
ASSERT_EQ(assembler.mov(x86::eax, Imm(i)), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, Imm(i)), ErrorCode::None);
|
||||
}
|
||||
ASSERT_EQ(program.size(), 10);
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace zasm::tests
|
||||
{
|
||||
ASSERT_NE(node, nullptr);
|
||||
|
||||
const auto& instr = node->get<zasm::Instruction>();
|
||||
const auto& instr = node->get<Instruction>();
|
||||
|
||||
const auto& imm = instr.getOperand<1, Imm>();
|
||||
ASSERT_EQ(imm.value<int>(), i);
|
||||
@@ -87,7 +87,7 @@ namespace zasm::tests
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
ASSERT_EQ(assembler.mov(x86::eax, Imm(i)), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, Imm(i)), ErrorCode::None);
|
||||
}
|
||||
ASSERT_EQ(program.size(), 10);
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace zasm::tests
|
||||
{
|
||||
ASSERT_NE(node, nullptr);
|
||||
|
||||
const auto& instr = node->get<zasm::Instruction>();
|
||||
const auto& instr = node->get<Instruction>();
|
||||
|
||||
const auto& imm = instr.getOperand<1, Imm>();
|
||||
ASSERT_EQ(imm.value<int>(), i);
|
||||
@@ -121,7 +121,7 @@ namespace zasm::tests
|
||||
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
ASSERT_EQ(assembler.mov(x86::eax, Imm(0)), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, Imm(0)), ErrorCode::None);
|
||||
ASSERT_EQ(program.size(), 1);
|
||||
|
||||
ASSERT_EQ(program.getHead(), program.getTail());
|
||||
@@ -136,7 +136,7 @@ namespace zasm::tests
|
||||
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
ASSERT_EQ(assembler.mov(x86::eax, Imm(0)), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, Imm(0)), ErrorCode::None);
|
||||
ASSERT_EQ(program.size(), 1);
|
||||
|
||||
ASSERT_EQ(program.getHead(), program.getTail());
|
||||
@@ -154,7 +154,7 @@ namespace zasm::tests
|
||||
Node* fifthNode = nullptr;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
ASSERT_EQ(assembler.mov(x86::eax, Imm(i)), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, Imm(i)), ErrorCode::None);
|
||||
if (i == 5)
|
||||
fifthNode = assembler.getCursor();
|
||||
}
|
||||
@@ -170,7 +170,7 @@ namespace zasm::tests
|
||||
{
|
||||
ASSERT_NE(node, nullptr);
|
||||
|
||||
const auto& instr = node->get<zasm::Instruction>();
|
||||
const auto& instr = node->get<Instruction>();
|
||||
|
||||
const auto& imm = instr.getOperand<1, Imm>();
|
||||
ASSERT_EQ(imm.value<int>(), NumberOrder[i]);
|
||||
@@ -190,7 +190,7 @@ namespace zasm::tests
|
||||
Node* fifthNode = nullptr;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
ASSERT_EQ(assembler.mov(x86::eax, Imm(i)), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, Imm(i)), ErrorCode::None);
|
||||
if (i == 5)
|
||||
fifthNode = assembler.getCursor();
|
||||
}
|
||||
@@ -206,7 +206,7 @@ namespace zasm::tests
|
||||
{
|
||||
ASSERT_NE(node, nullptr);
|
||||
|
||||
const auto& instr = node->get<zasm::Instruction>();
|
||||
const auto& instr = node->get<Instruction>();
|
||||
|
||||
const auto& imm = instr.getOperand<1, Imm>();
|
||||
ASSERT_EQ(imm.value<int>(), NumberOrder[i]);
|
||||
@@ -223,22 +223,22 @@ namespace zasm::tests
|
||||
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
ASSERT_EQ(assembler.mov(x86::eax, x86::ebx), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.xor_(x86::ebx, x86::edx), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.add(x86::eax, Imm(1)), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.not_(x86::eax), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.xor_(x86::eax, Imm(1)), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, x86::ebx), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.xor_(x86::ebx, x86::edx), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.add(x86::eax, Imm(1)), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.not_(x86::eax), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.xor_(x86::eax, Imm(1)), ErrorCode::None);
|
||||
|
||||
auto labelFoo = assembler.createLabel("foo");
|
||||
ASSERT_EQ(labelFoo.getId(), zasm::Label::Id{ 0 });
|
||||
ASSERT_EQ(labelFoo.getId(), Label::Id{ 0 });
|
||||
ASSERT_EQ(labelFoo.isValid(), true);
|
||||
ASSERT_EQ(assembler.bind(labelFoo), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::dword_ptr(x86::rip, labelFoo), x86::eax), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.bind(labelFoo), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.mov(x86::dword_ptr(x86::rip, labelFoo), x86::eax), ErrorCode::None);
|
||||
|
||||
ASSERT_EQ(program.size(), 7);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x400000), zasm::Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x400000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 18> expected = {
|
||||
0x89, 0xd8, 0x31, 0xd3, 0x83, 0xc0, 0x01, 0xf7, 0xd0, 0x83, 0xf0, 0x01, 0x89, 0x05, 0xfa, 0xff, 0xff, 0xff,
|
||||
@@ -269,41 +269,41 @@ namespace zasm::tests
|
||||
{
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
ASSERT_EQ(assembler.push(x86::rax), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.push(x86::rcx), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.push(x86::rdx), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.push(x86::rbx), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.push(x86::rbp), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.push(x86::rsi), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.push(x86::rdi), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.push(x86::r8), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.push(x86::r9), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.push(x86::r10), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.push(x86::r11), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.push(x86::r12), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.push(x86::r13), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.push(x86::r14), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.push(x86::r15), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.pushfq(), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.push(x86::rax), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.push(x86::rcx), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.push(x86::rdx), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.push(x86::rbx), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.push(x86::rbp), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.push(x86::rsi), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.push(x86::rdi), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.push(x86::r8), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.push(x86::r9), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.push(x86::r10), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.push(x86::r11), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.push(x86::r12), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.push(x86::r13), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.push(x86::r14), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.push(x86::r15), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.pushfq(), ErrorCode::None);
|
||||
|
||||
ASSERT_EQ(assembler.popfq(), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.pop(x86::r15), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.pop(x86::r14), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.pop(x86::r13), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.pop(x86::r12), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.pop(x86::r11), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.pop(x86::r10), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.pop(x86::r9), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.pop(x86::r8), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.pop(x86::rdi), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.pop(x86::rsi), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.pop(x86::rbp), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.pop(x86::rbx), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.pop(x86::rdx), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.pop(x86::rcx), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.pop(x86::rax), zasm::Error::None);
|
||||
ASSERT_EQ(assembler.popfq(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.pop(x86::r15), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.pop(x86::r14), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.pop(x86::r13), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.pop(x86::r12), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.pop(x86::r11), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.pop(x86::r10), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.pop(x86::r9), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.pop(x86::r8), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.pop(x86::rdi), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.pop(x86::rsi), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.pop(x86::rbp), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.pop(x86::rbx), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.pop(x86::rdx), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.pop(x86::rcx), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.pop(x86::rax), ErrorCode::None);
|
||||
|
||||
ASSERT_EQ(serializer.serialize(program, address), zasm::Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, address), ErrorCode::None);
|
||||
address += 0x10;
|
||||
|
||||
ASSERT_NE(serializer.getCodeSize(), 0);
|
||||
|
||||
@@ -11,10 +11,10 @@ namespace zasm::tests
|
||||
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
ASSERT_EQ(assembler.lea(x86::rax, x86::qword_ptr(0)), Error::None);
|
||||
ASSERT_EQ(assembler.lea(x86::rax, x86::qword_ptr(0)), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 8> expected = {
|
||||
0x48, 0x8D, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00,
|
||||
@@ -42,10 +42,10 @@ namespace zasm::tests
|
||||
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
ASSERT_EQ(assembler.lea(x86::eax, x86::dword_ptr(0)), Error::None);
|
||||
ASSERT_EQ(assembler.lea(x86::eax, x86::dword_ptr(0)), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 6> expected = {
|
||||
0x8D, 0x05, 0x00, 0x00, 0x00, 0x00,
|
||||
@@ -74,11 +74,11 @@ namespace zasm::tests
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
auto label = assembler.createLabel();
|
||||
ASSERT_EQ(assembler.bind(label), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, label), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, label), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 5> expected = {
|
||||
0xb8, 0x00, 0x10, 0x40, 0x00,
|
||||
@@ -107,11 +107,11 @@ namespace zasm::tests
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
auto label = assembler.createLabel();
|
||||
ASSERT_EQ(assembler.bind(label), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::rax, label), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.mov(x86::rax, label), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000401000000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000401000000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 10> expected = {
|
||||
0x48, 0xB8, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00,
|
||||
@@ -140,11 +140,11 @@ namespace zasm::tests
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
auto label = assembler.createLabel();
|
||||
ASSERT_EQ(assembler.bind(label), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, x86::dword_ptr(label)), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, x86::dword_ptr(label)), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 5> expected = {
|
||||
0xA1, 0x00, 0x10, 0x40, 0x00,
|
||||
@@ -173,12 +173,12 @@ namespace zasm::tests
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
auto label = assembler.createLabel();
|
||||
ASSERT_EQ(assembler.bind(label), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, x86::dword_ptr(label)), Error::None);
|
||||
ASSERT_EQ(assembler.embedLabel(label), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, x86::dword_ptr(label)), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.embedLabel(label), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
{
|
||||
const std::array<uint8_t, 9> expected = {
|
||||
@@ -207,7 +207,7 @@ namespace zasm::tests
|
||||
ASSERT_EQ(relocInfo02->offset, 5);
|
||||
}
|
||||
|
||||
ASSERT_EQ(serializer.relocate(0x0000000000501000), Error::None);
|
||||
ASSERT_EQ(serializer.relocate(0x0000000000501000), ErrorCode::None);
|
||||
|
||||
{
|
||||
const std::array<uint8_t, 9> expected = {
|
||||
@@ -244,12 +244,12 @@ namespace zasm::tests
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
auto label = assembler.createLabel();
|
||||
ASSERT_EQ(assembler.bind(label), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::rax, label), Error::None);
|
||||
ASSERT_EQ(assembler.embedLabel(label), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.mov(x86::rax, label), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.embedLabel(label), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000401000000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000401000000), ErrorCode::None);
|
||||
|
||||
{
|
||||
const std::array<uint8_t, 18> expected = {
|
||||
@@ -279,7 +279,7 @@ namespace zasm::tests
|
||||
ASSERT_EQ(relocInfo02->offset, 10);
|
||||
}
|
||||
|
||||
ASSERT_EQ(serializer.relocate(0x0000000501000000), Error::None);
|
||||
ASSERT_EQ(serializer.relocate(0x0000000501000000), ErrorCode::None);
|
||||
|
||||
{
|
||||
const std::array<uint8_t, 18> expected = {
|
||||
@@ -323,25 +323,25 @@ namespace zasm::tests
|
||||
auto labelC = a.createLabel();
|
||||
ASSERT_EQ(labelC.isValid(), true);
|
||||
|
||||
ASSERT_EQ(a.section(".text"), Error::None);
|
||||
ASSERT_EQ(a.section(".text"), ErrorCode::None);
|
||||
{
|
||||
ASSERT_EQ(a.lea(x86::rax, x86::qword_ptr(x86::rip, labelA)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rbx, x86::qword_ptr(x86::rip, labelB)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(x86::rip, labelC)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rax, x86::qword_ptr(x86::rip, labelA)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rbx, x86::qword_ptr(x86::rip, labelB)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(x86::rip, labelC)), ErrorCode::None);
|
||||
}
|
||||
|
||||
ASSERT_EQ(a.section(".data", Section::Attribs::Data), Error::None);
|
||||
ASSERT_EQ(a.section(".data", Section::Attribs::Data), ErrorCode::None);
|
||||
{
|
||||
ASSERT_EQ(a.bind(labelA), Error::None);
|
||||
ASSERT_EQ(a.dq(0x123456789), Error::None);
|
||||
ASSERT_EQ(a.bind(labelB), Error::None);
|
||||
ASSERT_EQ(a.dq(0x987654321), Error::None);
|
||||
ASSERT_EQ(a.bind(labelC), Error::None);
|
||||
ASSERT_EQ(a.dq(0xABCDEF123), Error::None);
|
||||
ASSERT_EQ(a.bind(labelA), ErrorCode::None);
|
||||
ASSERT_EQ(a.dq(0x123456789), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelB), ErrorCode::None);
|
||||
ASSERT_EQ(a.dq(0x987654321), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelC), ErrorCode::None);
|
||||
ASSERT_EQ(a.dq(0xABCDEF123), ErrorCode::None);
|
||||
}
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x00400000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x00400000), ErrorCode::None);
|
||||
|
||||
{
|
||||
ASSERT_EQ(serializer.getSectionCount(), 2);
|
||||
@@ -367,7 +367,7 @@ namespace zasm::tests
|
||||
std::string("8967452301000000214365870900000023F1DEBC0A000000"));
|
||||
}
|
||||
|
||||
ASSERT_EQ(serializer.relocate(0x00500000), Error::None);
|
||||
ASSERT_EQ(serializer.relocate(0x00500000), ErrorCode::None);
|
||||
|
||||
{
|
||||
ASSERT_EQ(serializer.getSectionCount(), 2);
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace zasm::tests
|
||||
auto label = assembler.createLabel();
|
||||
assembler.bind(label);
|
||||
}
|
||||
ASSERT_EQ(instrEntry.emitter(assembler), Error::None) << instrEntry.instrBytes << ", " << instrEntry.operation;
|
||||
ASSERT_EQ(instrEntry.emitter(assembler), ErrorCode::None) << instrEntry.instrBytes << ", " << instrEntry.operation;
|
||||
entries++;
|
||||
}
|
||||
}
|
||||
@@ -89,7 +89,7 @@ namespace zasm::tests
|
||||
|
||||
// Save Program.
|
||||
MemoryStream buf;
|
||||
ASSERT_EQ(save(outputProgram, buf), Error::None);
|
||||
ASSERT_EQ(save(outputProgram, buf), ErrorCode::None);
|
||||
|
||||
// Read the serialized data back into a separate program.
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace zasm::tests
|
||||
|
||||
// Save Program.
|
||||
const auto filePath = std::filesystem::temp_directory_path() / "saverestoretest.zasm";
|
||||
ASSERT_EQ(save(outputProgram, filePath), Error::None);
|
||||
ASSERT_EQ(save(outputProgram, filePath), ErrorCode::None);
|
||||
|
||||
// Read the serialized data back into a separate program.
|
||||
auto inputProgram = load(filePath);
|
||||
@@ -129,7 +129,7 @@ namespace zasm::tests
|
||||
|
||||
// Save Program.
|
||||
MemoryStream buf;
|
||||
ASSERT_EQ(save(outputProgram, buf), Error::None);
|
||||
ASSERT_EQ(save(outputProgram, buf), ErrorCode::None);
|
||||
|
||||
// Read the serialized data back into a separate program.
|
||||
buf.seek(0, SeekType::Begin);
|
||||
|
||||
@@ -16,14 +16,14 @@ namespace zasm::tests
|
||||
|
||||
// .text by default.
|
||||
{
|
||||
ASSERT_EQ(a.jmp(labelA), Error::None);
|
||||
ASSERT_EQ(a.nop(), Error::None);
|
||||
ASSERT_EQ(a.bind(labelA), Error::None);
|
||||
ASSERT_EQ(a.nop(), Error::None);
|
||||
ASSERT_EQ(a.jmp(labelA), ErrorCode::None);
|
||||
ASSERT_EQ(a.nop(), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelA), ErrorCode::None);
|
||||
ASSERT_EQ(a.nop(), ErrorCode::None);
|
||||
}
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x00400000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x00400000), ErrorCode::None);
|
||||
|
||||
ASSERT_EQ(serializer.getSectionCount(), 1);
|
||||
|
||||
@@ -48,25 +48,25 @@ namespace zasm::tests
|
||||
auto labelC = a.createLabel();
|
||||
ASSERT_EQ(labelC.isValid(), true);
|
||||
|
||||
ASSERT_EQ(a.section(".text"), Error::None);
|
||||
ASSERT_EQ(a.section(".text"), ErrorCode::None);
|
||||
{
|
||||
ASSERT_EQ(a.lea(x86::rax, x86::qword_ptr(x86::rip, labelA)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rbx, x86::qword_ptr(x86::rip, labelB)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(x86::rip, labelC)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rax, x86::qword_ptr(x86::rip, labelA)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rbx, x86::qword_ptr(x86::rip, labelB)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(x86::rip, labelC)), ErrorCode::None);
|
||||
}
|
||||
|
||||
ASSERT_EQ(a.section(".data", Section::Attribs::Data), Error::None);
|
||||
ASSERT_EQ(a.section(".data", Section::Attribs::Data), ErrorCode::None);
|
||||
{
|
||||
ASSERT_EQ(a.bind(labelA), Error::None);
|
||||
ASSERT_EQ(a.dq(0x123456789), Error::None);
|
||||
ASSERT_EQ(a.bind(labelB), Error::None);
|
||||
ASSERT_EQ(a.dq(0x987654321), Error::None);
|
||||
ASSERT_EQ(a.bind(labelC), Error::None);
|
||||
ASSERT_EQ(a.dq(0xABCDEF123), Error::None);
|
||||
ASSERT_EQ(a.bind(labelA), ErrorCode::None);
|
||||
ASSERT_EQ(a.dq(0x123456789), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelB), ErrorCode::None);
|
||||
ASSERT_EQ(a.dq(0x987654321), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelC), ErrorCode::None);
|
||||
ASSERT_EQ(a.dq(0xABCDEF123), ErrorCode::None);
|
||||
}
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x00400000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x00400000), ErrorCode::None);
|
||||
|
||||
ASSERT_EQ(serializer.getSectionCount(), 2);
|
||||
|
||||
@@ -104,33 +104,33 @@ namespace zasm::tests
|
||||
auto labelC = a.createLabel();
|
||||
ASSERT_EQ(labelC.isValid(), true);
|
||||
|
||||
ASSERT_EQ(a.section(".text"), Error::None);
|
||||
ASSERT_EQ(a.section(".text"), ErrorCode::None);
|
||||
{
|
||||
ASSERT_EQ(a.lea(x86::rax, x86::qword_ptr(x86::rip, labelA)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rbx, x86::qword_ptr(x86::rip, labelB)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(x86::rip, labelC)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rax, x86::qword_ptr(x86::rip, labelA)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rbx, x86::qword_ptr(x86::rip, labelB)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(x86::rip, labelC)), ErrorCode::None);
|
||||
}
|
||||
|
||||
// Identical name attrib align causes a merge.
|
||||
ASSERT_EQ(a.section(".text"), Error::None);
|
||||
ASSERT_EQ(a.section(".text"), ErrorCode::None);
|
||||
{
|
||||
ASSERT_EQ(a.lea(x86::rax, x86::qword_ptr(x86::rip, labelA)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rbx, x86::qword_ptr(x86::rip, labelB)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(x86::rip, labelC)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rax, x86::qword_ptr(x86::rip, labelA)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rbx, x86::qword_ptr(x86::rip, labelB)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(x86::rip, labelC)), ErrorCode::None);
|
||||
}
|
||||
|
||||
ASSERT_EQ(a.section(".data", Section::Attribs::Data), Error::None);
|
||||
ASSERT_EQ(a.section(".data", Section::Attribs::Data), ErrorCode::None);
|
||||
{
|
||||
ASSERT_EQ(a.bind(labelA), Error::None);
|
||||
ASSERT_EQ(a.dq(0x123456789), Error::None);
|
||||
ASSERT_EQ(a.bind(labelB), Error::None);
|
||||
ASSERT_EQ(a.dq(0x987654321), Error::None);
|
||||
ASSERT_EQ(a.bind(labelC), Error::None);
|
||||
ASSERT_EQ(a.dq(0xABCDEF123), Error::None);
|
||||
ASSERT_EQ(a.bind(labelA), ErrorCode::None);
|
||||
ASSERT_EQ(a.dq(0x123456789), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelB), ErrorCode::None);
|
||||
ASSERT_EQ(a.dq(0x987654321), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelC), ErrorCode::None);
|
||||
ASSERT_EQ(a.dq(0xABCDEF123), ErrorCode::None);
|
||||
}
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x00400000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x00400000), ErrorCode::None);
|
||||
|
||||
ASSERT_EQ(serializer.getSectionCount(), 2);
|
||||
|
||||
@@ -168,32 +168,32 @@ namespace zasm::tests
|
||||
auto labelC = a.createLabel();
|
||||
ASSERT_EQ(labelC.isValid(), true);
|
||||
|
||||
ASSERT_EQ(a.section(".text"), Error::None);
|
||||
ASSERT_EQ(a.section(".text"), ErrorCode::None);
|
||||
{
|
||||
ASSERT_EQ(a.lea(x86::rax, x86::qword_ptr(x86::rip, labelA)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rbx, x86::qword_ptr(x86::rip, labelB)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(x86::rip, labelC)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rax, x86::qword_ptr(x86::rip, labelA)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rbx, x86::qword_ptr(x86::rip, labelB)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(x86::rip, labelC)), ErrorCode::None);
|
||||
}
|
||||
|
||||
ASSERT_EQ(a.section(".text", Section::Attribs::Exec), Error::None);
|
||||
ASSERT_EQ(a.section(".text", Section::Attribs::Exec), ErrorCode::None);
|
||||
{
|
||||
ASSERT_EQ(a.lea(x86::rax, x86::qword_ptr(x86::rip, labelA)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rbx, x86::qword_ptr(x86::rip, labelB)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(x86::rip, labelC)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rax, x86::qword_ptr(x86::rip, labelA)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rbx, x86::qword_ptr(x86::rip, labelB)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(x86::rip, labelC)), ErrorCode::None);
|
||||
}
|
||||
|
||||
ASSERT_EQ(a.section(".data", Section::Attribs::Data), Error::None);
|
||||
ASSERT_EQ(a.section(".data", Section::Attribs::Data), ErrorCode::None);
|
||||
{
|
||||
ASSERT_EQ(a.bind(labelA), Error::None);
|
||||
ASSERT_EQ(a.dq(0x123456789), Error::None);
|
||||
ASSERT_EQ(a.bind(labelB), Error::None);
|
||||
ASSERT_EQ(a.dq(0x987654321), Error::None);
|
||||
ASSERT_EQ(a.bind(labelC), Error::None);
|
||||
ASSERT_EQ(a.dq(0xABCDEF123), Error::None);
|
||||
ASSERT_EQ(a.bind(labelA), ErrorCode::None);
|
||||
ASSERT_EQ(a.dq(0x123456789), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelB), ErrorCode::None);
|
||||
ASSERT_EQ(a.dq(0x987654321), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelC), ErrorCode::None);
|
||||
ASSERT_EQ(a.dq(0xABCDEF123), ErrorCode::None);
|
||||
}
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x00400000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x00400000), ErrorCode::None);
|
||||
|
||||
ASSERT_EQ(serializer.getSectionCount(), 3);
|
||||
|
||||
@@ -241,20 +241,20 @@ namespace zasm::tests
|
||||
auto labelC = a.createLabel();
|
||||
ASSERT_EQ(labelC.isValid(), true);
|
||||
|
||||
ASSERT_EQ(a.section(".text"), Error::None);
|
||||
ASSERT_EQ(a.section(".text"), ErrorCode::None);
|
||||
{
|
||||
ASSERT_EQ(a.bind(labelA), Error::None);
|
||||
ASSERT_EQ(a.jmp(labelB), Error::None);
|
||||
ASSERT_EQ(a.bind(labelA), ErrorCode::None);
|
||||
ASSERT_EQ(a.jmp(labelB), ErrorCode::None);
|
||||
}
|
||||
|
||||
ASSERT_EQ(a.section(".text2", Section::Attribs::Code), Error::None);
|
||||
ASSERT_EQ(a.section(".text2", Section::Attribs::Code), ErrorCode::None);
|
||||
{
|
||||
ASSERT_EQ(a.bind(labelB), Error::None);
|
||||
ASSERT_EQ(a.jmp(labelA), Error::None);
|
||||
ASSERT_EQ(a.bind(labelB), ErrorCode::None);
|
||||
ASSERT_EQ(a.jmp(labelA), ErrorCode::None);
|
||||
}
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x00400000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x00400000), ErrorCode::None);
|
||||
ASSERT_EQ(serializer.getSectionCount(), 2);
|
||||
|
||||
const auto* sectInfo01 = serializer.getSectionInfo(0);
|
||||
@@ -287,20 +287,20 @@ namespace zasm::tests
|
||||
auto labelC = a.createLabel();
|
||||
ASSERT_EQ(labelC.isValid(), true);
|
||||
|
||||
ASSERT_EQ(a.section(".text"), Error::None);
|
||||
ASSERT_EQ(a.section(".text"), ErrorCode::None);
|
||||
{
|
||||
ASSERT_EQ(a.bind(labelA), Error::None);
|
||||
ASSERT_EQ(a.jz(labelB), Error::None);
|
||||
ASSERT_EQ(a.bind(labelA), ErrorCode::None);
|
||||
ASSERT_EQ(a.jz(labelB), ErrorCode::None);
|
||||
}
|
||||
|
||||
ASSERT_EQ(a.section(".text2", Section::Attribs::Code), Error::None);
|
||||
ASSERT_EQ(a.section(".text2", Section::Attribs::Code), ErrorCode::None);
|
||||
{
|
||||
ASSERT_EQ(a.bind(labelB), Error::None);
|
||||
ASSERT_EQ(a.jz(labelA), Error::None);
|
||||
ASSERT_EQ(a.bind(labelB), ErrorCode::None);
|
||||
ASSERT_EQ(a.jz(labelA), ErrorCode::None);
|
||||
}
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x00400000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x00400000), ErrorCode::None);
|
||||
ASSERT_EQ(serializer.getSectionCount(), 2);
|
||||
|
||||
const auto* sectInfo01 = serializer.getSectionInfo(0);
|
||||
|
||||
@@ -9,10 +9,10 @@ namespace zasm::tests
|
||||
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
ASSERT_EQ(assembler.mov(x86::rax, x86::qword_ptr(x86::fs, 0x30)), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::rax, x86::qword_ptr(x86::fs, 0x30)), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 8> expected = {
|
||||
0x64, 0x67, 0x48, 0xA1, 0x30, 0x00, 0x00, 0x00,
|
||||
@@ -33,10 +33,10 @@ namespace zasm::tests
|
||||
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
ASSERT_EQ(assembler.mov(x86::eax, x86::dword_ptr(x86::fs, 0x30)), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, x86::dword_ptr(x86::fs, 0x30)), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 5> expected = {
|
||||
0x64, 0x67, 0xA1, 0x30, 0x00,
|
||||
@@ -57,10 +57,10 @@ namespace zasm::tests
|
||||
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
ASSERT_EQ(assembler.mov(x86::rax, x86::qword_ptr(x86::gs, 0x30)), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::rax, x86::qword_ptr(x86::gs, 0x30)), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 8> expected = {
|
||||
0x65, 0x67, 0x48, 0xA1, 0x30, 0x00, 0x00, 0x00,
|
||||
@@ -81,10 +81,10 @@ namespace zasm::tests
|
||||
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
ASSERT_EQ(assembler.mov(x86::eax, x86::dword_ptr(x86::gs, 0x30)), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::eax, x86::dword_ptr(x86::gs, 0x30)), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 5> expected = {
|
||||
0x65, 0x67, 0xA1, 0x30, 0x00,
|
||||
@@ -99,4 +99,4 @@ namespace zasm::tests
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace zasm::tests
|
||||
} // namespace zasm::tests
|
||||
|
||||
@@ -10,10 +10,10 @@ namespace zasm::tests
|
||||
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
ASSERT_EQ(assembler.lea(x86::rax, x86::qword_ptr(0)), Error::None);
|
||||
ASSERT_EQ(assembler.lea(x86::rax, x86::qword_ptr(0)), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 8> expected = {
|
||||
0x48, 0x8D, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00,
|
||||
@@ -34,10 +34,10 @@ namespace zasm::tests
|
||||
|
||||
x86::Assembler assembler(program);
|
||||
|
||||
ASSERT_EQ(assembler.lea(x86::eax, x86::dword_ptr(0)), Error::None);
|
||||
ASSERT_EQ(assembler.lea(x86::eax, x86::dword_ptr(0)), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 6> expected = {
|
||||
0x8D, 0x05, 0x00, 0x00, 0x00, 0x00,
|
||||
@@ -60,12 +60,12 @@ namespace zasm::tests
|
||||
|
||||
auto label = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.lea(x86::rax, x86::qword_ptr(x86::rip, label)), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label), Error::None);
|
||||
ASSERT_EQ(assembler.dq(0x123C312F21329F31ULL), Error::None);
|
||||
ASSERT_EQ(assembler.lea(x86::rax, x86::qword_ptr(x86::rip, label)), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.dq(0x123C312F21329F31ULL), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 15> expected = {
|
||||
0x48, 0x8D, 0x05, 0x00, 0x00, 0x00, 0x00, 0x31, 0x9F, 0x32, 0x21, 0x2F, 0x31, 0x3C, 0x12,
|
||||
@@ -88,12 +88,12 @@ namespace zasm::tests
|
||||
|
||||
auto label = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.lea(x86::eax, x86::dword_ptr(label)), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label), Error::None);
|
||||
ASSERT_EQ(assembler.dq(0x123C312F21329F31ULL), Error::None);
|
||||
ASSERT_EQ(assembler.lea(x86::eax, x86::dword_ptr(label)), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.dq(0x123C312F21329F31ULL), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 14> expected = { 0x8D, 0x05, 0x06, 0x10, 0x40, 0x00, 0x31,
|
||||
0x9F, 0x32, 0x21, 0x2F, 0x31, 0x3C, 0x12 };
|
||||
@@ -115,14 +115,14 @@ namespace zasm::tests
|
||||
|
||||
auto label = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.jmp(label), Error::None);
|
||||
ASSERT_EQ(assembler.jmp(label), ErrorCode::None);
|
||||
for (int i = 0; i < 124; i++)
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label), Error::None);
|
||||
ASSERT_EQ(assembler.int3(), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.int3(), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 127> expected = {
|
||||
0xEB, 0x7C, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
|
||||
@@ -151,15 +151,15 @@ namespace zasm::tests
|
||||
|
||||
auto label = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.jmp(label), Error::None);
|
||||
ASSERT_EQ(assembler.jmp(label), ErrorCode::None);
|
||||
for (int i = 0; i < 100; i++)
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.align(Align::Type::Code, 16), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label), Error::None);
|
||||
ASSERT_EQ(assembler.int3(), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.align(Align::Type::Code, 16), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.int3(), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 113> expected = {
|
||||
0xEB, 0x6E, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
|
||||
@@ -192,15 +192,15 @@ namespace zasm::tests
|
||||
|
||||
auto label = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.jmp(label), Error::None);
|
||||
ASSERT_EQ(assembler.jmp(label), ErrorCode::None);
|
||||
for (int i = 0; i < 124; i++)
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.align(Align::Type::Code, 32), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label), Error::None);
|
||||
ASSERT_EQ(assembler.int3(), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.align(Align::Type::Code, 32), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.int3(), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 161> expected = {
|
||||
0xE9, 0x9B, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
|
||||
@@ -232,14 +232,14 @@ namespace zasm::tests
|
||||
|
||||
auto label = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.bind(label), Error::None);
|
||||
ASSERT_EQ(assembler.int3(), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.int3(), ErrorCode::None);
|
||||
for (int i = 0; i < 124; i++)
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.jmp(label), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.jmp(label), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 127> expected = {
|
||||
0xCC, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
|
||||
@@ -268,14 +268,14 @@ namespace zasm::tests
|
||||
|
||||
auto label = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.bind(label), Error::None);
|
||||
ASSERT_EQ(assembler.int3(), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.int3(), ErrorCode::None);
|
||||
for (int i = 0; i < 124; i++)
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.jmp(label), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.jmp(label), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 127> expected = {
|
||||
0xCC, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
|
||||
@@ -304,14 +304,14 @@ namespace zasm::tests
|
||||
|
||||
auto label = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.bind(label), Error::None);
|
||||
ASSERT_EQ(assembler.int3(), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.int3(), ErrorCode::None);
|
||||
for (int i = 0; i < 125; i++)
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.jmp(label), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.jmp(label), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 131> expected = {
|
||||
0xCC, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
|
||||
@@ -340,14 +340,14 @@ namespace zasm::tests
|
||||
|
||||
auto label = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.bind(label), Error::None);
|
||||
ASSERT_EQ(assembler.int3(), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.int3(), ErrorCode::None);
|
||||
for (int i = 0; i < 125; i++)
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.jmp(label), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.jmp(label), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 131> expected = {
|
||||
0xCC, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
|
||||
@@ -376,12 +376,12 @@ namespace zasm::tests
|
||||
|
||||
auto label01 = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.lea(x86::rax, x86::qword_ptr(label01)), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.lea(x86::rax, x86::qword_ptr(label01)), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::UnresolvedLabel);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::UnresolvedLabel);
|
||||
}
|
||||
|
||||
TEST(SerializationTests, UnBoundLabelRegression01)
|
||||
@@ -406,67 +406,69 @@ namespace zasm::tests
|
||||
Label labelImpExitProcess = program.getOrCreateImportLabel("kernel32.dll", "ExitProcess");
|
||||
Label labelImpMessageBoxA = program.getOrCreateImportLabel("user32.dll", "MessageBoxA");
|
||||
|
||||
ASSERT_EQ(a.section(".text", Section::Attribs::Code | Section::Attribs::Exec | Section::Attribs::Read), Error::None);
|
||||
ASSERT_EQ(a.bind(labelMain), Error::None);
|
||||
ASSERT_EQ(a.sub(x86::rsp, Imm(0x28)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(labelRData01)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rax, x86::qword_ptr(x86::rdx)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(labelData01)), Error::None);
|
||||
ASSERT_EQ(a.mov(x86::qword_ptr(x86::rdx), x86::rax), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(labelRData02)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rax, x86::qword_ptr(x86::rdx)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(labelData02)), Error::None);
|
||||
ASSERT_EQ(a.mov(x86::qword_ptr(x86::rdx), x86::rax), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(labelRData03)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rax, x86::qword_ptr(x86::rdx)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(labelData03)), Error::None);
|
||||
ASSERT_EQ(a.mov(x86::qword_ptr(x86::rdx), x86::rax), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(labelRData04)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rax, x86::qword_ptr(x86::rdx)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(labelData04)), Error::None);
|
||||
ASSERT_EQ(a.mov(x86::qword_ptr(x86::rdx), x86::rax), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(labelRData05)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rax, x86::qword_ptr(x86::rdx)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(labelData05)), Error::None);
|
||||
ASSERT_EQ(a.mov(x86::qword_ptr(x86::rdx), x86::rax), Error::None);
|
||||
ASSERT_EQ(a.xor_(x86::rcx, x86::rcx), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(labelStrMessage)), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::r8, x86::qword_ptr(labelStrTitle)), Error::None);
|
||||
ASSERT_EQ(a.mov(x86::r9, Imm(0)), Error::None);
|
||||
ASSERT_EQ(a.call(x86::qword_ptr(labelImpMessageBoxA)), Error::None);
|
||||
ASSERT_EQ(a.xor_(x86::rcx, x86::rcx), Error::None);
|
||||
ASSERT_EQ(a.call(x86::qword_ptr(labelImpExitProcess)), Error::None);
|
||||
ASSERT_EQ(a.add(x86::rsp, Imm(0x28)), Error::None);
|
||||
ASSERT_EQ(a.ret(), Error::None);
|
||||
ASSERT_EQ(
|
||||
a.section(".text", Section::Attribs::Code | Section::Attribs::Exec | Section::Attribs::Read), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelMain), ErrorCode::None);
|
||||
ASSERT_EQ(a.sub(x86::rsp, Imm(0x28)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(labelRData01)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rax, x86::qword_ptr(x86::rdx)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(labelData01)), ErrorCode::None);
|
||||
ASSERT_EQ(a.mov(x86::qword_ptr(x86::rdx), x86::rax), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(labelRData02)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rax, x86::qword_ptr(x86::rdx)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(labelData02)), ErrorCode::None);
|
||||
ASSERT_EQ(a.mov(x86::qword_ptr(x86::rdx), x86::rax), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(labelRData03)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rax, x86::qword_ptr(x86::rdx)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(labelData03)), ErrorCode::None);
|
||||
ASSERT_EQ(a.mov(x86::qword_ptr(x86::rdx), x86::rax), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(labelRData04)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rax, x86::qword_ptr(x86::rdx)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(labelData04)), ErrorCode::None);
|
||||
ASSERT_EQ(a.mov(x86::qword_ptr(x86::rdx), x86::rax), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(labelRData05)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rax, x86::qword_ptr(x86::rdx)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(labelData05)), ErrorCode::None);
|
||||
ASSERT_EQ(a.mov(x86::qword_ptr(x86::rdx), x86::rax), ErrorCode::None);
|
||||
ASSERT_EQ(a.xor_(x86::rcx, x86::rcx), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rdx, x86::qword_ptr(labelStrMessage)), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::r8, x86::qword_ptr(labelStrTitle)), ErrorCode::None);
|
||||
ASSERT_EQ(a.mov(x86::r9, Imm(0)), ErrorCode::None);
|
||||
ASSERT_EQ(a.call(x86::qword_ptr(labelImpMessageBoxA)), ErrorCode::None);
|
||||
ASSERT_EQ(a.xor_(x86::rcx, x86::rcx), ErrorCode::None);
|
||||
ASSERT_EQ(a.call(x86::qword_ptr(labelImpExitProcess)), ErrorCode::None);
|
||||
ASSERT_EQ(a.add(x86::rsp, Imm(0x28)), ErrorCode::None);
|
||||
ASSERT_EQ(a.ret(), ErrorCode::None);
|
||||
|
||||
ASSERT_EQ(a.section(".data", Section::Attribs::Data | Section::Attribs::Read | Section::Attribs::Write), Error::None);
|
||||
ASSERT_EQ(a.bind(labelData01), Error::None);
|
||||
ASSERT_EQ(a.dq(01), Error::None);
|
||||
ASSERT_EQ(a.bind(labelData02), Error::None);
|
||||
ASSERT_EQ(a.dq(02), Error::None);
|
||||
ASSERT_EQ(a.bind(labelData03), Error::None);
|
||||
ASSERT_EQ(a.dq(03), Error::None);
|
||||
ASSERT_EQ(a.bind(labelData04), Error::None);
|
||||
ASSERT_EQ(a.dq(04), Error::None);
|
||||
ASSERT_EQ(a.bind(labelData05), Error::None);
|
||||
ASSERT_EQ(a.dq(05), Error::None);
|
||||
ASSERT_EQ(
|
||||
a.section(".data", Section::Attribs::Data | Section::Attribs::Read | Section::Attribs::Write), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelData01), ErrorCode::None);
|
||||
ASSERT_EQ(a.dq(01), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelData02), ErrorCode::None);
|
||||
ASSERT_EQ(a.dq(02), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelData03), ErrorCode::None);
|
||||
ASSERT_EQ(a.dq(03), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelData04), ErrorCode::None);
|
||||
ASSERT_EQ(a.dq(04), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelData05), ErrorCode::None);
|
||||
ASSERT_EQ(a.dq(05), ErrorCode::None);
|
||||
|
||||
ASSERT_EQ(a.section(".rdata", Section::Attribs::RData | Section::Attribs::Read), Error::None);
|
||||
ASSERT_EQ(a.bind(labelStrMessage), Error::None);
|
||||
ASSERT_EQ(a.embed("Hello World", 12), Error::None);
|
||||
ASSERT_EQ(a.bind(labelRData01), Error::None);
|
||||
ASSERT_EQ(a.dq(01), Error::None);
|
||||
ASSERT_EQ(a.bind(labelRData02), Error::None);
|
||||
ASSERT_EQ(a.dq(02), Error::None);
|
||||
ASSERT_EQ(a.bind(labelRData03), Error::None);
|
||||
ASSERT_EQ(a.dq(03), Error::None);
|
||||
ASSERT_EQ(a.bind(labelRData04), Error::None);
|
||||
ASSERT_EQ(a.dq(04), Error::None);
|
||||
ASSERT_EQ(a.bind(labelRData05), Error::None);
|
||||
ASSERT_EQ(a.dq(05), Error::None);
|
||||
ASSERT_EQ(a.section(".rdata", Section::Attribs::RData | Section::Attribs::Read), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelStrMessage), ErrorCode::None);
|
||||
ASSERT_EQ(a.embed("Hello World", 12), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelRData01), ErrorCode::None);
|
||||
ASSERT_EQ(a.dq(01), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelRData02), ErrorCode::None);
|
||||
ASSERT_EQ(a.dq(02), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelRData03), ErrorCode::None);
|
||||
ASSERT_EQ(a.dq(03), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelRData04), ErrorCode::None);
|
||||
ASSERT_EQ(a.dq(04), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelRData05), ErrorCode::None);
|
||||
ASSERT_EQ(a.dq(05), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::UnresolvedLabel);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::UnresolvedLabel);
|
||||
}
|
||||
|
||||
TEST(SerializationTests, EmbeddedLabelX64)
|
||||
@@ -477,13 +479,13 @@ namespace zasm::tests
|
||||
|
||||
auto label01 = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.bind(label01), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.embedLabel(label01), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.embedLabel(label01), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 10> expected = { 0x90, 0x90, 0x00, 0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
ASSERT_EQ(serializer.getCodeSize(), expected.size());
|
||||
@@ -504,13 +506,13 @@ namespace zasm::tests
|
||||
|
||||
auto label01 = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.bind(label01), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.embedLabel(label01), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.embedLabel(label01), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 6> expected = { 0x90, 0x90, 0x00, 0x10, 0x40, 0x00 };
|
||||
ASSERT_EQ(serializer.getCodeSize(), expected.size());
|
||||
@@ -532,14 +534,14 @@ namespace zasm::tests
|
||||
auto label01 = assembler.createLabel();
|
||||
auto label02 = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.bind(label01), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label02), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.embedLabelRel(label02, label01, BitSize::_8), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label02), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.embedLabelRel(label02, label01, BitSize::_8), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 3> expected = { 0x90, 0x90, 0x01 };
|
||||
ASSERT_EQ(serializer.getCodeSize(), expected.size());
|
||||
@@ -561,14 +563,14 @@ namespace zasm::tests
|
||||
auto label01 = assembler.createLabel();
|
||||
auto label02 = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.bind(label01), Error::None);
|
||||
ASSERT_EQ(assembler.embedLabelRel(label02, label01, BitSize::_8), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label02), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.embedLabelRel(label02, label01, BitSize::_8), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label02), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 3> expected = { 0x02, 0x90, 0x90 };
|
||||
ASSERT_EQ(serializer.getCodeSize(), expected.size());
|
||||
@@ -590,14 +592,14 @@ namespace zasm::tests
|
||||
auto label01 = assembler.createLabel();
|
||||
auto label02 = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.bind(label01), Error::None);
|
||||
ASSERT_EQ(assembler.embedLabelRel(label01, label02, BitSize::_8), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label02), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.embedLabelRel(label01, label02, BitSize::_8), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label02), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 3> expected = { 0xFE, 0x90, 0x90 };
|
||||
ASSERT_EQ(serializer.getCodeSize(), expected.size());
|
||||
@@ -619,14 +621,14 @@ namespace zasm::tests
|
||||
auto label01 = assembler.createLabel();
|
||||
auto label02 = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.bind(label01), Error::None);
|
||||
ASSERT_EQ(assembler.embedLabelRel(label02, label01, BitSize::_16), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label02), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.embedLabelRel(label02, label01, BitSize::_16), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label02), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 4> expected = { 0x03, 0x00, 0x90, 0x90 };
|
||||
ASSERT_EQ(serializer.getCodeSize(), expected.size());
|
||||
@@ -648,14 +650,14 @@ namespace zasm::tests
|
||||
auto label01 = assembler.createLabel();
|
||||
auto label02 = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.bind(label01), Error::None);
|
||||
ASSERT_EQ(assembler.embedLabelRel(label01, label02, BitSize::_16), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label02), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.embedLabelRel(label01, label02, BitSize::_16), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label02), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 4> expected = { 0xFD, 0xFF, 0x90, 0x90 };
|
||||
ASSERT_EQ(serializer.getCodeSize(), expected.size());
|
||||
@@ -677,14 +679,14 @@ namespace zasm::tests
|
||||
auto label01 = assembler.createLabel();
|
||||
auto label02 = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.bind(label01), Error::None);
|
||||
ASSERT_EQ(assembler.embedLabelRel(label02, label01, BitSize::_32), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label02), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.embedLabelRel(label02, label01, BitSize::_32), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label02), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 6> expected = { 0x05, 0x00, 0x00, 0x00, 0x90, 0x90 };
|
||||
ASSERT_EQ(serializer.getCodeSize(), expected.size());
|
||||
@@ -706,14 +708,14 @@ namespace zasm::tests
|
||||
auto label01 = assembler.createLabel();
|
||||
auto label02 = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.bind(label01), Error::None);
|
||||
ASSERT_EQ(assembler.embedLabelRel(label01, label02, BitSize::_32), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label02), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.embedLabelRel(label01, label02, BitSize::_32), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label02), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 6> expected = { 0xFB, 0xFF, 0xFF, 0xFF, 0x90, 0x90 };
|
||||
ASSERT_EQ(serializer.getCodeSize(), expected.size());
|
||||
@@ -734,12 +736,12 @@ namespace zasm::tests
|
||||
|
||||
auto label01 = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.db(0xCC, 16), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), Error::None);
|
||||
ASSERT_EQ(assembler.embedLabel(label01), Error::None);
|
||||
ASSERT_EQ(assembler.db(0xCC, 16), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.embedLabel(label01), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 24> expected = {
|
||||
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
|
||||
@@ -763,12 +765,12 @@ namespace zasm::tests
|
||||
|
||||
auto label01 = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.dw(0x1234, 8), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), Error::None);
|
||||
ASSERT_EQ(assembler.embedLabel(label01), Error::None);
|
||||
ASSERT_EQ(assembler.dw(0x1234, 8), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.embedLabel(label01), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 24> expected = {
|
||||
0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, 0x12,
|
||||
@@ -792,12 +794,12 @@ namespace zasm::tests
|
||||
|
||||
auto label01 = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.dd(0x12345678, 4), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), Error::None);
|
||||
ASSERT_EQ(assembler.embedLabel(label01), Error::None);
|
||||
ASSERT_EQ(assembler.dd(0x12345678, 4), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.embedLabel(label01), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 24> expected = {
|
||||
0x78, 0x56, 0x34, 0x12, 0x78, 0x56, 0x34, 0x12, 0x78, 0x56, 0x34, 0x12,
|
||||
@@ -821,12 +823,12 @@ namespace zasm::tests
|
||||
|
||||
auto label01 = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.dq(0x12345678AABBCCEE, 2), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), Error::None);
|
||||
ASSERT_EQ(assembler.embedLabel(label01), Error::None);
|
||||
ASSERT_EQ(assembler.dq(0x12345678AABBCCEE, 2), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.embedLabel(label01), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 24> expected = {
|
||||
0xEE, 0xCC, 0xBB, 0xAA, 0x78, 0x56, 0x34, 0x12, 0xEE, 0xCC, 0xBB, 0xAA,
|
||||
@@ -850,14 +852,14 @@ namespace zasm::tests
|
||||
|
||||
auto label01 = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.db(0xCC, 4), Error::None);
|
||||
ASSERT_EQ(assembler.db(0xCC, 4), ErrorCode::None);
|
||||
|
||||
ASSERT_EQ(assembler.align(Align::Type::Data, 8), Error::None);
|
||||
ASSERT_EQ(assembler.align(Align::Type::Data, 8), ErrorCode::None);
|
||||
|
||||
ASSERT_EQ(assembler.bind(label01), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 8> expected = {
|
||||
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
|
||||
@@ -882,14 +884,14 @@ namespace zasm::tests
|
||||
|
||||
auto label01 = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.db(0xCC, 4), Error::None);
|
||||
ASSERT_EQ(assembler.db(0xCC, 4), ErrorCode::None);
|
||||
|
||||
ASSERT_EQ(assembler.align(Align::Type::Data, 16), Error::None);
|
||||
ASSERT_EQ(assembler.align(Align::Type::Data, 16), ErrorCode::None);
|
||||
|
||||
ASSERT_EQ(assembler.bind(label01), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 16> expected = {
|
||||
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
|
||||
@@ -914,14 +916,14 @@ namespace zasm::tests
|
||||
|
||||
auto label01 = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.db(0xCC, 4), Error::None);
|
||||
ASSERT_EQ(assembler.db(0xCC, 4), ErrorCode::None);
|
||||
|
||||
ASSERT_EQ(assembler.align(Align::Type::Data, 32), Error::None);
|
||||
ASSERT_EQ(assembler.align(Align::Type::Data, 32), ErrorCode::None);
|
||||
|
||||
ASSERT_EQ(assembler.bind(label01), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 32> expected = {
|
||||
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
|
||||
@@ -947,14 +949,14 @@ namespace zasm::tests
|
||||
|
||||
auto label01 = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.inc(x86::eax), Error::None);
|
||||
ASSERT_EQ(assembler.inc(x86::eax), ErrorCode::None);
|
||||
|
||||
ASSERT_EQ(assembler.align(Align::Type::Code, 8), Error::None);
|
||||
ASSERT_EQ(assembler.align(Align::Type::Code, 8), ErrorCode::None);
|
||||
|
||||
ASSERT_EQ(assembler.bind(label01), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 8> expected = {
|
||||
0xFF, 0xC0, 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00,
|
||||
@@ -979,14 +981,14 @@ namespace zasm::tests
|
||||
|
||||
auto label01 = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.inc(x86::eax), Error::None);
|
||||
ASSERT_EQ(assembler.inc(x86::eax), ErrorCode::None);
|
||||
|
||||
ASSERT_EQ(assembler.align(Align::Type::Code, 16), Error::None);
|
||||
ASSERT_EQ(assembler.align(Align::Type::Code, 16), ErrorCode::None);
|
||||
|
||||
ASSERT_EQ(assembler.bind(label01), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 16> expected = {
|
||||
0xFF, 0xC0, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00,
|
||||
@@ -1011,14 +1013,14 @@ namespace zasm::tests
|
||||
|
||||
auto label01 = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.inc(x86::eax), Error::None);
|
||||
ASSERT_EQ(assembler.inc(x86::eax), ErrorCode::None);
|
||||
|
||||
ASSERT_EQ(assembler.align(Align::Type::Code, 32), Error::None);
|
||||
ASSERT_EQ(assembler.align(Align::Type::Code, 32), ErrorCode::None);
|
||||
|
||||
ASSERT_EQ(assembler.bind(label01), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 32> expected = {
|
||||
0xFF, 0xC0, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00,
|
||||
@@ -1038,12 +1040,12 @@ namespace zasm::tests
|
||||
|
||||
TEST(SerializationTests, SerializeDecodedSwapNodes)
|
||||
{
|
||||
zasm::Program program(zasm::MachineMode::I386);
|
||||
std::vector<zasm::Node*> tails = {};
|
||||
Program program(MachineMode::I386);
|
||||
std::vector<Node*> tails = {};
|
||||
|
||||
{
|
||||
zasm::x86::Assembler a(program);
|
||||
zasm::Decoder decoder(zasm::MachineMode::I386);
|
||||
x86::Assembler a(program);
|
||||
Decoder decoder(MachineMode::I386);
|
||||
|
||||
const std::array<uint8_t, 12> raw_data = {
|
||||
0xB8, 0x00, 0x10, 0x40, 0x00, // mov eax, [blabla]
|
||||
@@ -1069,15 +1071,15 @@ namespace zasm::tests
|
||||
auto bind_node = program.bindLabel(label);
|
||||
program.moveBefore(tails[4], *bind_node);
|
||||
|
||||
tails[3]->getIf<zasm::Instruction>()->setOperand(0, label);
|
||||
tails[3]->getIf<Instruction>()->setOperand(0, label);
|
||||
|
||||
zasm::x86::Assembler a(program);
|
||||
x86::Assembler a(program);
|
||||
a.setCursor(tails[4]);
|
||||
a.xor_(zasm::x86::eax, zasm::x86::eax);
|
||||
a.xor_(x86::eax, x86::eax);
|
||||
|
||||
zasm::Serializer serializer{};
|
||||
Serializer serializer{};
|
||||
auto r = serializer.serialize(program, 0x406000);
|
||||
ASSERT_EQ(r, zasm::Error::None);
|
||||
ASSERT_EQ(r, ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 14> expected = { 0xB8, 0x00, 0x10, 0x40, 0x00, 0x83, 0xF8,
|
||||
0x00, 0x90, 0xEB, 0x00, 0xC3, 0x31, 0xC0 };
|
||||
@@ -1099,10 +1101,10 @@ namespace zasm::tests
|
||||
auto reg = x86::rdx;
|
||||
auto address = (uint64_t)0x0000000000401000;
|
||||
|
||||
ASSERT_EQ(assembler.mov(x86::Gp64(reg.getId()), x86::qword_ptr(x86::rip, (uintptr_t)address)), Error::None);
|
||||
ASSERT_EQ(assembler.mov(x86::Gp64(reg.getId()), x86::qword_ptr(x86::rip, (uintptr_t)address)), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<std::uint8_t, 7> expected = { 0x48, 0x8B, 0x15, 0xF9, 0xFF, 0xFF, 0xFF };
|
||||
ASSERT_EQ(serializer.getCodeSize(), expected.size());
|
||||
@@ -1125,21 +1127,21 @@ namespace zasm::tests
|
||||
auto label02 = assembler.createLabel();
|
||||
auto label03 = assembler.createLabel();
|
||||
|
||||
ASSERT_EQ(assembler.bind(label03), Error::None);
|
||||
ASSERT_EQ(assembler.jmp(label01), Error::None);
|
||||
ASSERT_EQ(assembler.nop(), Error::None);
|
||||
ASSERT_EQ(assembler.align(Align::Type::Code, 8), Error::None);
|
||||
ASSERT_EQ(assembler.jmp(label02), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label01), Error::None);
|
||||
ASSERT_EQ(assembler.int3(), Error::None);
|
||||
ASSERT_EQ(assembler.align(Align::Type::Code, 10), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label02), Error::None);
|
||||
ASSERT_EQ(assembler.int3(), Error::None);
|
||||
ASSERT_EQ(assembler.jmp(label03), Error::None);
|
||||
ASSERT_EQ(assembler.align(Align::Type::Code, 10), Error::None);
|
||||
ASSERT_EQ(assembler.bind(label03), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.jmp(label01), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.nop(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.align(Align::Type::Code, 8), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.jmp(label02), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label01), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.int3(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.align(Align::Type::Code, 10), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.bind(label02), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.int3(), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.jmp(label03), ErrorCode::None);
|
||||
ASSERT_EQ(assembler.align(Align::Type::Code, 10), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x0000000000401000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 30> expected = {
|
||||
0xEB, 0x08, 0x90, 0x0F, 0x1F, 0x44, 0x00, 0x00, 0xEB, 0x0A, 0xCC, 0x0F, 0x1F, 0x84, 0x00,
|
||||
@@ -1166,14 +1168,14 @@ namespace zasm::tests
|
||||
x86::Assembler a(program);
|
||||
|
||||
auto label = a.createLabel();
|
||||
ASSERT_EQ(a.push(x86::rbp), Error::None);
|
||||
ASSERT_EQ(a.lea(x86::rbp, x86::qword_ptr(x86::rip, label)), Error::None);
|
||||
ASSERT_EQ(a.xchg(x86::qword_ptr(x86::rsp), x86::rbp), Error::None);
|
||||
ASSERT_EQ(a.ret(), Error::None);
|
||||
ASSERT_EQ(a.bind(label), Error::None);
|
||||
ASSERT_EQ(a.push(x86::rbp), ErrorCode::None);
|
||||
ASSERT_EQ(a.lea(x86::rbp, x86::qword_ptr(x86::rip, label)), ErrorCode::None);
|
||||
ASSERT_EQ(a.xchg(x86::qword_ptr(x86::rsp), x86::rbp), ErrorCode::None);
|
||||
ASSERT_EQ(a.ret(), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(label), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x140015000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x140015000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 13> expected = {
|
||||
0x55, 0x48, 0x8D, 0x2D, 0x05, 0x00, 0x00, 0x00, 0x48, 0x87, 0x2C, 0x24, 0xC3,
|
||||
@@ -1195,10 +1197,10 @@ namespace zasm::tests
|
||||
Program program(MachineMode::AMD64);
|
||||
|
||||
x86::Assembler a(program);
|
||||
ASSERT_EQ(a.mov(x86::rax, x86::qword_ptr(x86::rax, x86::rbp)), Error::None);
|
||||
ASSERT_EQ(a.mov(x86::rax, x86::qword_ptr(x86::rax, x86::rbp)), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
ASSERT_EQ(serializer.serialize(program, 0x140015000), Error::None);
|
||||
ASSERT_EQ(serializer.serialize(program, 0x140015000), ErrorCode::None);
|
||||
|
||||
const std::array<uint8_t, 4> expected = { 0x48, 0x8B, 0x04, 0x28 };
|
||||
ASSERT_EQ(serializer.getCodeSize(), expected.size());
|
||||
@@ -1211,4 +1213,69 @@ namespace zasm::tests
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SerializationTests, TestSerializationErrorImpossibleInstruction)
|
||||
{
|
||||
Program program(MachineMode::AMD64);
|
||||
|
||||
x86::Assembler a(program);
|
||||
ASSERT_EQ(a.and_(x86::rbp, Imm64(0x123456789ABCDF)), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
auto res = serializer.serialize(program, 0x140015000);
|
||||
ASSERT_EQ(res, ErrorCode::ImpossibleInstruction);
|
||||
|
||||
ASSERT_EQ(
|
||||
res.getErrorMessage(),
|
||||
std::string("Error at node \"and rbp, 0x123456789abcdf\" with id 0: Impossible instruction"));
|
||||
}
|
||||
|
||||
TEST(SerializationTests, TestSerializationJecxzBad)
|
||||
{
|
||||
Program program(MachineMode::AMD64);
|
||||
|
||||
x86::Assembler a(program);
|
||||
auto labelLoop = a.createLabel();
|
||||
ASSERT_EQ(a.jecxz(labelLoop), ErrorCode::None);
|
||||
ASSERT_EQ(a.dd(0, 256), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelLoop), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
auto res = serializer.serialize(program, 0x140015000);
|
||||
ASSERT_EQ(res, ErrorCode::AddressOutOfRange);
|
||||
|
||||
ASSERT_EQ(res.getErrorMessage(), std::string("Error at node \"jecxz L0\" with id 0: Label out of range for operand 0"));
|
||||
}
|
||||
|
||||
TEST(SerializationTests, TestSerializationJecxzGood)
|
||||
{
|
||||
Program program(MachineMode::AMD64);
|
||||
|
||||
x86::Assembler a(program);
|
||||
auto labelLoop = a.createLabel();
|
||||
ASSERT_EQ(a.jecxz(labelLoop), ErrorCode::None);
|
||||
ASSERT_EQ(a.dd(0), ErrorCode::None);
|
||||
ASSERT_EQ(a.bind(labelLoop), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
auto res = serializer.serialize(program, 0x140015000);
|
||||
ASSERT_EQ(res, ErrorCode::None);
|
||||
}
|
||||
|
||||
TEST(SerializationTests, TestBadMemoryDisplacement)
|
||||
{
|
||||
Program program(MachineMode::AMD64);
|
||||
|
||||
x86::Assembler a(program);
|
||||
ASSERT_EQ(a.mov(x86::rax, x86::qword_ptr(x86::rip, 0xF23456789)), ErrorCode::None);
|
||||
|
||||
Serializer serializer;
|
||||
auto res = serializer.serialize(program, 0x140015000);
|
||||
ASSERT_EQ(res, ErrorCode::AddressOutOfRange);
|
||||
|
||||
ASSERT_EQ(
|
||||
res.getErrorMessage(),
|
||||
std::string("Error at node \"mov rax, qword ptr ds:[rel 0xf23456789]\" with id 0: Displacement out of range for "
|
||||
"operand 1"));
|
||||
}
|
||||
|
||||
} // namespace zasm::tests
|
||||
|
||||
@@ -44,6 +44,6 @@ namespace zasm::tests
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Error& err)
|
||||
{
|
||||
return os << zasm::getErrorName(err);
|
||||
return os << err.getErrorName();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,269 @@
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <zasm/core/errors.hpp>
|
||||
|
||||
namespace zasm
|
||||
{
|
||||
static constexpr std::uint64_t kErrorExtBit = 0x8000000000000000ULL;
|
||||
|
||||
struct ErrorExt
|
||||
{
|
||||
ErrorCode code;
|
||||
std::string message;
|
||||
};
|
||||
|
||||
// TODO: This is not fully portable so we should check for systems where
|
||||
// we have to use a different approach.
|
||||
static ErrorExt* toErrorExt(std::uint64_t data) noexcept
|
||||
{
|
||||
assert((data & kErrorExtBit) != 0);
|
||||
|
||||
auto* ext = reinterpret_cast<ErrorExt*>(data & ~kErrorExtBit);
|
||||
return ext;
|
||||
}
|
||||
|
||||
static std::uint64_t toInternalErrorData(const ErrorExt* ext) noexcept
|
||||
{
|
||||
return static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(ext)) | kErrorExtBit;
|
||||
}
|
||||
|
||||
static bool isExtError(std::uint64_t data) noexcept
|
||||
{
|
||||
return (data & kErrorExtBit) != 0;
|
||||
}
|
||||
|
||||
Error::Error(const Error& other)
|
||||
{
|
||||
if (isExtError(other._data))
|
||||
{
|
||||
const auto* ext = toErrorExt(other._data);
|
||||
|
||||
auto* newExt = new ErrorExt(*ext);
|
||||
_data = toInternalErrorData(newExt);
|
||||
}
|
||||
else
|
||||
{
|
||||
_data = other._data;
|
||||
}
|
||||
}
|
||||
|
||||
Error::Error(Error&& other) noexcept
|
||||
{
|
||||
_data = other._data;
|
||||
other._data = 0;
|
||||
}
|
||||
|
||||
Error::Error(ErrorCode code) noexcept
|
||||
{
|
||||
std::uint64_t data = static_cast<std::uint64_t>(code);
|
||||
_data = data;
|
||||
}
|
||||
|
||||
Error::Error(ErrorCode code, const char* message)
|
||||
{
|
||||
assert(message != nullptr);
|
||||
|
||||
auto* ext = new ErrorExt();
|
||||
ext->code = code;
|
||||
ext->message = message;
|
||||
|
||||
_data = toInternalErrorData(ext);
|
||||
}
|
||||
|
||||
Error::~Error() noexcept
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void Error::clear()
|
||||
{
|
||||
if (isExtError(_data))
|
||||
{
|
||||
const auto* ext = toErrorExt(_data);
|
||||
delete ext;
|
||||
}
|
||||
_data = 0;
|
||||
}
|
||||
|
||||
bool Error::empty() const noexcept
|
||||
{
|
||||
return _data == 0;
|
||||
}
|
||||
|
||||
bool Error::operator==(ErrorCode code) const noexcept
|
||||
{
|
||||
return getCode() == code;
|
||||
}
|
||||
|
||||
bool Error::operator!=(ErrorCode code) const noexcept
|
||||
{
|
||||
return !(*this == code);
|
||||
}
|
||||
|
||||
Error& Error::operator=(Error&& other) noexcept
|
||||
{
|
||||
clear();
|
||||
|
||||
_data = other._data;
|
||||
other._data = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Error& Error::operator=(const Error& other) noexcept
|
||||
{
|
||||
clear();
|
||||
|
||||
if (isExtError(other._data))
|
||||
{
|
||||
const auto* ext = toErrorExt(other._data);
|
||||
|
||||
auto* newExt = new ErrorExt(*ext);
|
||||
_data = toInternalErrorData(newExt);
|
||||
}
|
||||
else
|
||||
{
|
||||
_data = other._data;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
static ErrorCode getErrorCode(std::uint64_t data) noexcept
|
||||
{
|
||||
if (data == 0)
|
||||
{
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
if (isExtError(data))
|
||||
{
|
||||
const auto* ext = toErrorExt(data);
|
||||
return ext->code;
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<ErrorCode>(data);
|
||||
}
|
||||
}
|
||||
|
||||
ErrorCode Error::getCode() const noexcept
|
||||
{
|
||||
return getErrorCode(_data);
|
||||
}
|
||||
|
||||
static constexpr const char* getErrorCodeName(ErrorCode err) noexcept
|
||||
{
|
||||
#define ERROR_STRING(e) \
|
||||
case e: \
|
||||
return #e
|
||||
|
||||
switch (err)
|
||||
{
|
||||
ERROR_STRING(ErrorCode::None);
|
||||
ERROR_STRING(ErrorCode::InvalidMode);
|
||||
ERROR_STRING(ErrorCode::NotInitialized);
|
||||
ERROR_STRING(ErrorCode::InvalidOperation);
|
||||
ERROR_STRING(ErrorCode::InvalidParameter);
|
||||
ERROR_STRING(ErrorCode::FileNotFound);
|
||||
ERROR_STRING(ErrorCode::AccessDenied);
|
||||
ERROR_STRING(ErrorCode::OutOfMemory);
|
||||
ERROR_STRING(ErrorCode::LabelNotFound);
|
||||
ERROR_STRING(ErrorCode::UnresolvedLabel);
|
||||
ERROR_STRING(ErrorCode::InvalidLabel);
|
||||
ERROR_STRING(ErrorCode::LabelAlreadyBound);
|
||||
ERROR_STRING(ErrorCode::SectionNotFound);
|
||||
ERROR_STRING(ErrorCode::SectionAlreadyBound);
|
||||
ERROR_STRING(ErrorCode::SignatureMismatch);
|
||||
ERROR_STRING(ErrorCode::InvalidInstruction);
|
||||
ERROR_STRING(ErrorCode::OutOfBounds);
|
||||
ERROR_STRING(ErrorCode::ImpossibleInstruction);
|
||||
ERROR_STRING(ErrorCode::EmptyState);
|
||||
ERROR_STRING(ErrorCode::ImpossibleRelocation);
|
||||
ERROR_STRING(ErrorCode::AddressOutOfRange);
|
||||
ERROR_STRING(ErrorCode::InstructionTooLong);
|
||||
ERROR_STRING(ErrorCode::ExternalLabelNotBindable);
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
#undef ERROR_STRING
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char* Error::getErrorName() const noexcept
|
||||
{
|
||||
return getErrorCodeName(getCode());
|
||||
}
|
||||
|
||||
static const char* getErrorCodeMessage(ErrorCode err) noexcept
|
||||
{
|
||||
// Give a default message for known error codes.
|
||||
switch (err)
|
||||
{
|
||||
case ErrorCode::None:
|
||||
return "No error";
|
||||
case ErrorCode::InvalidMode:
|
||||
return "Invalid mode";
|
||||
case ErrorCode::NotInitialized:
|
||||
return "Not initialized";
|
||||
case ErrorCode::InvalidOperation:
|
||||
return "Invalid operation";
|
||||
case ErrorCode::InvalidParameter:
|
||||
return "Invalid parameter";
|
||||
case ErrorCode::FileNotFound:
|
||||
return "File not found";
|
||||
case ErrorCode::AccessDenied:
|
||||
return "Access denied";
|
||||
case ErrorCode::OutOfMemory:
|
||||
return "Out of memory";
|
||||
case ErrorCode::LabelNotFound:
|
||||
return "Label not found";
|
||||
case ErrorCode::UnresolvedLabel:
|
||||
return "Unresolved label";
|
||||
case ErrorCode::InvalidLabel:
|
||||
return "Invalid label";
|
||||
case ErrorCode::LabelAlreadyBound:
|
||||
return "Label already bound";
|
||||
case ErrorCode::SectionNotFound:
|
||||
return "Section not found";
|
||||
case ErrorCode::SectionAlreadyBound:
|
||||
return "Section already bound";
|
||||
case ErrorCode::SignatureMismatch:
|
||||
return "Signature mismatch";
|
||||
case ErrorCode::InvalidInstruction:
|
||||
return "Invalid instruction";
|
||||
case ErrorCode::OutOfBounds:
|
||||
return "Out of bounds";
|
||||
case ErrorCode::ImpossibleInstruction:
|
||||
return "Impossible instruction";
|
||||
case ErrorCode::EmptyState:
|
||||
return "Empty state";
|
||||
case ErrorCode::ImpossibleRelocation:
|
||||
return "Impossible relocation";
|
||||
case ErrorCode::ExternalLabelNotBindable:
|
||||
return "External label can not be bound";
|
||||
case ErrorCode::InstructionTooLong:
|
||||
return "Instruction too long";
|
||||
case ErrorCode::AddressOutOfRange:
|
||||
return "Address out of range";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "<invalid error code>";
|
||||
}
|
||||
|
||||
const char* Error::getErrorMessage() const noexcept
|
||||
{
|
||||
if (isExtError(_data))
|
||||
{
|
||||
const auto* ext = toErrorExt(_data);
|
||||
return ext->message.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
return getErrorCodeMessage(getCode());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace zasm
|
||||
@@ -94,7 +94,7 @@ namespace zasm
|
||||
#endif
|
||||
if (fp == nullptr)
|
||||
{
|
||||
return Error::AccessDenied;
|
||||
return ErrorCode::AccessDenied;
|
||||
}
|
||||
|
||||
// Adjust the buffer size
|
||||
@@ -108,7 +108,7 @@ namespace zasm
|
||||
seek(0, SeekType::Begin);
|
||||
|
||||
_state->mode = mode;
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
bool FileStream::isOpen() const
|
||||
|
||||
@@ -109,10 +109,19 @@ namespace zasm
|
||||
break;
|
||||
}
|
||||
|
||||
if (status != ZYAN_STATUS_SUCCESS)
|
||||
switch (status)
|
||||
{
|
||||
// TODO: Translate proper error.
|
||||
_status = Error::NotInitialized;
|
||||
case ZYAN_STATUS_SUCCESS:
|
||||
break;
|
||||
case ZYAN_STATUS_INVALID_ARGUMENT:
|
||||
_status = Error{ ErrorCode::InvalidParameter };
|
||||
break;
|
||||
case ZYAN_STATUS_INVALID_OPERATION:
|
||||
_status = Error{ ErrorCode::InvalidOperation };
|
||||
break;
|
||||
default:
|
||||
_status = Error{ ErrorCode::NotInitialized };
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,7 +167,7 @@ namespace zasm
|
||||
|
||||
Decoder::Result Decoder::decode(const void* data, const std::size_t len, std::uint64_t address) noexcept
|
||||
{
|
||||
if (_status != Error::None)
|
||||
if (_status != ErrorCode::None)
|
||||
{
|
||||
return zasm::makeUnexpected(_status);
|
||||
}
|
||||
@@ -169,8 +178,20 @@ namespace zasm
|
||||
ZyanStatus status = ZydisDecoderDecodeFull(&_decoder, data, len, &instr, instrOps.data());
|
||||
if (status != ZYAN_STATUS_SUCCESS)
|
||||
{
|
||||
// TODO: Translate proper error.
|
||||
return zasm::makeUnexpected(Error::InvalidOperation);
|
||||
switch (status)
|
||||
{
|
||||
case ZYDIS_STATUS_NO_MORE_DATA:
|
||||
_status = Error{ ErrorCode::OutOfBounds };
|
||||
break;
|
||||
case ZYDIS_STATUS_INSTRUCTION_TOO_LONG:
|
||||
_status = Error{ ErrorCode::InstructionTooLong };
|
||||
break;
|
||||
default:
|
||||
_status = Error{ ErrorCode::InvalidInstruction };
|
||||
break;
|
||||
}
|
||||
|
||||
return zasm::makeUnexpected(_status);
|
||||
}
|
||||
|
||||
InstructionDetail::CPUFlags flags{};
|
||||
@@ -207,4 +228,14 @@ namespace zasm
|
||||
return res;
|
||||
}
|
||||
|
||||
MachineMode Decoder::getMode() const
|
||||
{
|
||||
return _mode;
|
||||
}
|
||||
|
||||
const Error& Decoder::getLastError() const
|
||||
{
|
||||
return _status;
|
||||
}
|
||||
|
||||
} // namespace zasm
|
||||
|
||||
@@ -180,7 +180,8 @@ namespace zasm
|
||||
}
|
||||
}
|
||||
|
||||
assert(desiredBranchType != ZydisBranchType::ZYDIS_BRANCH_TYPE_NONE);
|
||||
// If desiredBranchType is ZYDIS_BRANCH_TYPE_NONE it means we can not fit the address
|
||||
// into the instruction, this is an error and should be handled by the caller.
|
||||
|
||||
return { res, desiredBranchType };
|
||||
}
|
||||
@@ -190,7 +191,7 @@ namespace zasm
|
||||
dst.type = ZydisOperandType::ZYDIS_OPERAND_TYPE_REGISTER;
|
||||
dst.reg.value = static_cast<ZydisRegister>(src.getId());
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static int64_t getTemporaryRel(EncoderState& state) noexcept
|
||||
@@ -236,11 +237,16 @@ namespace zasm
|
||||
const auto targetAddress = labelVA.has_value() ? *labelVA : immValue;
|
||||
|
||||
const auto [addrRel, branchType] = processRelAddress(encodeInfo, ctx, targetAddress);
|
||||
if (branchType == ZydisBranchType::ZYDIS_BRANCH_TYPE_NONE)
|
||||
{
|
||||
char msg[128];
|
||||
std::snprintf(msg, sizeof(msg), "Label out of range for operand %zu", state.operandIndex);
|
||||
|
||||
return Error(ErrorCode::AddressOutOfRange, msg);
|
||||
}
|
||||
|
||||
immValue = addrRel;
|
||||
desiredBranchType = branchType;
|
||||
|
||||
assert(desiredBranchType != ZydisBranchType::ZYDIS_BRANCH_TYPE_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -269,7 +275,7 @@ namespace zasm
|
||||
dst.type = ZydisOperandType::ZYDIS_OPERAND_TYPE_IMMEDIATE;
|
||||
dst.imm.s = immValue;
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error buildOperand_(ZydisEncoderOperand& dst, EncoderState& state, const Imm& src)
|
||||
@@ -298,7 +304,7 @@ namespace zasm
|
||||
dst.type = ZydisOperandType::ZYDIS_OPERAND_TYPE_IMMEDIATE;
|
||||
dst.imm.s = immValue;
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error buildOperand_(ZydisEncoderOperand& dst, EncoderState& state, const Mem& src)
|
||||
@@ -384,6 +390,13 @@ namespace zasm
|
||||
if (isDisplacementValid)
|
||||
{
|
||||
displacement = displacement - (address + instrSize);
|
||||
if (std::abs(displacement) > std::numeric_limits<std::int32_t>::max())
|
||||
{
|
||||
char msg[128];
|
||||
std::snprintf(msg, sizeof(msg), "Displacement out of range for operand %zu", state.operandIndex);
|
||||
|
||||
return Error(ErrorCode::AddressOutOfRange, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -408,14 +421,14 @@ namespace zasm
|
||||
state.req.prefixes |= ZYDIS_ATTRIB_HAS_SEGMENT_FS;
|
||||
}
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error buildOperand_(
|
||||
ZydisEncoderOperand& dst, [[maybe_unused]] EncoderState& state, [[maybe_unused]] const Operand::None& src) noexcept
|
||||
{
|
||||
dst.type = ZydisOperandType::ZYDIS_OPERAND_TYPE_UNUSED;
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error buildOperand(ZydisEncoderOperand& dst, EncoderState& state, const Operand& src)
|
||||
@@ -506,7 +519,7 @@ namespace zasm
|
||||
{
|
||||
if (!validateMachineMode(mode))
|
||||
{
|
||||
return Error::InvalidMode;
|
||||
return ErrorCode::InvalidMode;
|
||||
}
|
||||
|
||||
res.buffer.length = 0;
|
||||
@@ -548,7 +561,7 @@ namespace zasm
|
||||
{
|
||||
auto& dstOp = req.operands[state.operandIndex]; // NOLINT
|
||||
const auto& srcOp = operands[state.operandIndex]; // NOLINT
|
||||
if (auto opStatus = buildOperand(dstOp, state, srcOp); opStatus != Error::None)
|
||||
if (auto opStatus = buildOperand(dstOp, state, srcOp); opStatus != ErrorCode::None)
|
||||
{
|
||||
return opStatus;
|
||||
}
|
||||
@@ -564,7 +577,7 @@ namespace zasm
|
||||
break;
|
||||
case ZYDIS_STATUS_IMPOSSIBLE_INSTRUCTION:
|
||||
default:
|
||||
return Error::ImpossibleInstruction;
|
||||
return ErrorCode::ImpossibleInstruction;
|
||||
}
|
||||
|
||||
res.buffer.length = static_cast<std::uint8_t>(bufLen);
|
||||
@@ -572,7 +585,7 @@ namespace zasm
|
||||
res.relocData = state.relocData;
|
||||
res.relocLabel = state.relocLabel;
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
Expected<EncoderResult, Error> encode(
|
||||
@@ -580,7 +593,7 @@ namespace zasm
|
||||
const Operand* operands)
|
||||
{
|
||||
EncoderResult res;
|
||||
if (auto err = encode_(res, nullptr, mode, attribs, mnemonic, numOps, operands); err != Error::None)
|
||||
if (auto err = encode_(res, nullptr, mode, attribs, mnemonic, numOps, operands); err != ErrorCode::None)
|
||||
{
|
||||
return makeUnexpected(err);
|
||||
}
|
||||
@@ -596,7 +609,8 @@ namespace zasm
|
||||
// encode_ will set this to kHintRequiresSize in case a length is required for correct encoding.
|
||||
ctx.instrSize = 0;
|
||||
|
||||
if (const auto encodeError = encode_(res, &ctx, mode, prefixes, mnemonic, numOps, operands); encodeError != Error::None)
|
||||
if (const auto encodeError = encode_(res, &ctx, mode, prefixes, mnemonic, numOps, operands);
|
||||
encodeError != ErrorCode::None)
|
||||
{
|
||||
return makeUnexpected(encodeError);
|
||||
}
|
||||
@@ -606,7 +620,7 @@ namespace zasm
|
||||
// Encode with now known size, instruction size can change again in this call.
|
||||
ctx.instrSize = res.buffer.length;
|
||||
if (const auto encodeError = encode_(res, &ctx, mode, prefixes, mnemonic, numOps, operands);
|
||||
encodeError != Error::None)
|
||||
encodeError != ErrorCode::None)
|
||||
{
|
||||
return makeUnexpected(encodeError);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace zasm::formatter
|
||||
public:
|
||||
static constexpr std::size_t kInlineCapacity = 64;
|
||||
|
||||
Program* program{};
|
||||
const Program* program{};
|
||||
Options options{};
|
||||
|
||||
union
|
||||
@@ -41,7 +41,7 @@ namespace zasm::formatter
|
||||
, options(opts)
|
||||
{
|
||||
}
|
||||
constexpr Context(Program& prog, Options opts)
|
||||
constexpr Context(const Program& prog, Options opts)
|
||||
: program(&prog)
|
||||
, options(opts)
|
||||
{
|
||||
@@ -337,11 +337,11 @@ namespace zasm::formatter
|
||||
{
|
||||
if (disp < 0)
|
||||
{
|
||||
ctx.format("0x%" PRIx64, -disp);
|
||||
ctx.format("0x%02" PRIx64, -disp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx.format("0x%" PRIx64, disp);
|
||||
ctx.format("0x%02" PRIx64, disp);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -488,7 +488,7 @@ namespace zasm::formatter
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx.format(".section");
|
||||
ctx.appendLiteral(".section");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -548,7 +548,7 @@ namespace zasm::formatter
|
||||
|
||||
} // namespace detail
|
||||
|
||||
std::string toString(Program& program, const Node* node, Options options /*= kDefaultOptions*/)
|
||||
std::string toString(const Program& program, const Node* node, Options options /*= kDefaultOptions*/)
|
||||
{
|
||||
if (node == nullptr)
|
||||
{
|
||||
@@ -562,12 +562,13 @@ namespace zasm::formatter
|
||||
return { ctx.data(), ctx.size };
|
||||
}
|
||||
|
||||
std::string toString(Program& program, Options options /*= {}*/)
|
||||
std::string toString(const Program& program, Options options /*= {}*/)
|
||||
{
|
||||
return toString(program, program.getHead(), nullptr, options);
|
||||
}
|
||||
|
||||
std::string toString(Program& program, const Node* nodeFrom, const Node* nodeTo, Options options /*= kDefaultOptions*/)
|
||||
std::string toString(
|
||||
const Program& program, const Node* nodeFrom, const Node* nodeTo, Options options /*= kDefaultOptions*/)
|
||||
{
|
||||
auto ctx = detail::Context(program, options);
|
||||
|
||||
@@ -587,7 +588,7 @@ namespace zasm::formatter
|
||||
return { ctx.data(), ctx.size };
|
||||
}
|
||||
|
||||
std::string toString(Program& program, const Instruction* instr, Options options /*= kDefaultOptions*/)
|
||||
std::string toString(const Program& program, const Instruction* instr, Options options /*= kDefaultOptions*/)
|
||||
{
|
||||
if (instr == nullptr)
|
||||
{
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace zasm
|
||||
|
||||
if (decoded.getVisibleOperandCount() != opCount)
|
||||
{
|
||||
return zasm::makeUnexpected(Error::InvalidOperation);
|
||||
return zasm::makeUnexpected(Error{ ErrorCode::InvalidOperation });
|
||||
}
|
||||
|
||||
// Replace the decoded operands with user specified operands.
|
||||
|
||||
@@ -528,18 +528,18 @@ namespace zasm
|
||||
const auto entryIdx = static_cast<std::size_t>(label.getId());
|
||||
if (entryIdx >= _state->labels.size())
|
||||
{
|
||||
return makeUnexpected(Error::InvalidLabel);
|
||||
return makeUnexpected(Error{ ErrorCode::InvalidLabel });
|
||||
}
|
||||
|
||||
auto& entry = _state->labels[entryIdx];
|
||||
if ((entry.flags & LabelFlags::External) != LabelFlags::None)
|
||||
{
|
||||
return makeUnexpected(Error::ExternalLabelNotBindable);
|
||||
return makeUnexpected(Error{ ErrorCode::ExternalLabelNotBindable });
|
||||
}
|
||||
|
||||
if (entry.node != nullptr)
|
||||
{
|
||||
return makeUnexpected(Error::LabelAlreadyBound);
|
||||
return makeUnexpected(Error{ ErrorCode::LabelAlreadyBound });
|
||||
}
|
||||
|
||||
auto* node = createNode_(*_state, label);
|
||||
@@ -595,13 +595,13 @@ namespace zasm
|
||||
{
|
||||
if (!label.isValid())
|
||||
{
|
||||
return zasm::makeUnexpected(Error::InvalidLabel);
|
||||
return zasm::makeUnexpected(Error{ ErrorCode::InvalidLabel });
|
||||
}
|
||||
|
||||
const auto entryIdx = static_cast<std::size_t>(label.getId());
|
||||
if (entryIdx >= _state->labels.size())
|
||||
{
|
||||
return makeUnexpected(Error::InvalidLabel);
|
||||
return makeUnexpected(Error{ ErrorCode::InvalidLabel });
|
||||
}
|
||||
|
||||
const auto& entry = _state->labels[entryIdx];
|
||||
@@ -638,7 +638,7 @@ namespace zasm
|
||||
const auto entryIdx = static_cast<std::size_t>(sectionId);
|
||||
if (entryIdx >= prog.sections.size())
|
||||
{
|
||||
return makeUnexpected(Error::SectionNotFound);
|
||||
return makeUnexpected(Error{ ErrorCode::SectionNotFound });
|
||||
}
|
||||
return &prog.sections[entryIdx];
|
||||
}
|
||||
@@ -654,7 +654,7 @@ namespace zasm
|
||||
auto& entry = sectEntry.value();
|
||||
if (entry->node != nullptr)
|
||||
{
|
||||
return makeUnexpected(Error::SectionAlreadyBound);
|
||||
return makeUnexpected(Error{ ErrorCode::SectionAlreadyBound });
|
||||
}
|
||||
|
||||
auto* node = createNode_(*_state, section);
|
||||
@@ -679,7 +679,7 @@ namespace zasm
|
||||
{
|
||||
if (name == nullptr)
|
||||
{
|
||||
return Error::InvalidParameter;
|
||||
return ErrorCode::InvalidParameter;
|
||||
}
|
||||
|
||||
auto sectEntry = getSectionData(*_state, section.getId());
|
||||
@@ -697,7 +697,7 @@ namespace zasm
|
||||
}
|
||||
|
||||
entry->nameId = _state->symbolNames.aquire(name);
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
std::int32_t Program::getSectionAlign(const Section& section) noexcept
|
||||
@@ -716,7 +716,7 @@ namespace zasm
|
||||
{
|
||||
if (align <= 0)
|
||||
{
|
||||
return Error::InvalidParameter;
|
||||
return ErrorCode::InvalidParameter;
|
||||
}
|
||||
|
||||
auto sectEntry = getSectionData(*_state, section.getId());
|
||||
@@ -728,7 +728,7 @@ namespace zasm
|
||||
auto* entry = sectEntry.value();
|
||||
entry->align = align;
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
} // namespace zasm
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace zasm
|
||||
|
||||
std::vector<std::uint8_t> buf;
|
||||
buf.resize(size);
|
||||
if (auto err = helper.read(buf.data(), size); err != Error::None)
|
||||
if (auto err = helper.read(buf.data(), size); err != ErrorCode::None)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@@ -84,7 +84,7 @@ namespace zasm
|
||||
|
||||
template<> Error loadOperand_<Operand::None>(SaveRestore& helper, Operand&)
|
||||
{
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
template<> Error loadOperand_<Reg>(SaveRestore& helper, Operand& op)
|
||||
@@ -94,7 +94,7 @@ namespace zasm
|
||||
|
||||
op = Reg(regId);
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
template<> Error loadOperand_<Mem>(SaveRestore& helper, Operand& op)
|
||||
@@ -117,7 +117,7 @@ namespace zasm
|
||||
|
||||
op = Mem(bitSize, Reg(regSeg), Label(labelId), Reg(regBase), Reg(regIdx), scale, disp);
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
template<> Error loadOperand_<Imm>(SaveRestore& helper, Operand& op)
|
||||
@@ -127,7 +127,7 @@ namespace zasm
|
||||
|
||||
op = Imm(val);
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
template<> Error loadOperand_<Label>(SaveRestore& helper, Operand& op)
|
||||
@@ -137,7 +137,7 @@ namespace zasm
|
||||
|
||||
op = Label(labelId);
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
template<> Node* loadNode_<Instruction>(SaveRestore& helper, Program& program)
|
||||
@@ -162,31 +162,31 @@ namespace zasm
|
||||
switch (opType)
|
||||
{
|
||||
case OperandType::None:
|
||||
if (auto err = loadOperand_<Operand::None>(helper, op); err != Error::None)
|
||||
if (auto err = loadOperand_<Operand::None>(helper, op); err != ErrorCode::None)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
case OperandType::Register:
|
||||
if (auto err = loadOperand_<Reg>(helper, op); err != Error::None)
|
||||
if (auto err = loadOperand_<Reg>(helper, op); err != ErrorCode::None)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
case OperandType::Memory:
|
||||
if (auto err = loadOperand_<Mem>(helper, op); err != Error::None)
|
||||
if (auto err = loadOperand_<Mem>(helper, op); err != ErrorCode::None)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
case OperandType::Immediate:
|
||||
if (auto err = loadOperand_<Imm>(helper, op); err != Error::None)
|
||||
if (auto err = loadOperand_<Imm>(helper, op); err != ErrorCode::None)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
case OperandType::Label:
|
||||
if (auto err = loadOperand_<Label>(helper, op); err != Error::None)
|
||||
if (auto err = loadOperand_<Label>(helper, op); err != ErrorCode::None)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@@ -244,7 +244,7 @@ namespace zasm
|
||||
|
||||
if (node == nullptr)
|
||||
{
|
||||
return Error::InvalidParameter;
|
||||
return ErrorCode::InvalidParameter;
|
||||
}
|
||||
|
||||
auto* intl = static_cast<detail::Node*>(node);
|
||||
@@ -253,7 +253,7 @@ namespace zasm
|
||||
|
||||
program.append(node);
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error loadNodes(SaveRestore& helper, Program& program)
|
||||
@@ -263,13 +263,13 @@ namespace zasm
|
||||
helper >> nodeCount;
|
||||
for (std::uint64_t i = 0; i < nodeCount; ++i)
|
||||
{
|
||||
if (auto err = loadNode(helper, program); err != Error::None)
|
||||
if (auto err = loadNode(helper, program); err != ErrorCode::None)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error loadLabels(SaveRestore& helper, Program& program)
|
||||
@@ -306,7 +306,7 @@ namespace zasm
|
||||
labels.push_back(labelData);
|
||||
}
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error loadSections(SaveRestore& helper, Program& program)
|
||||
@@ -343,7 +343,7 @@ namespace zasm
|
||||
sections.push_back(sectData);
|
||||
}
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error loadSymbols(SaveRestore& helper, Program& program)
|
||||
@@ -352,26 +352,26 @@ namespace zasm
|
||||
auto& programState = program.getState();
|
||||
auto& symbols = programState.symbolNames;
|
||||
|
||||
if (auto err = symbols.load(stream); err != Error::None)
|
||||
if (auto err = symbols.load(stream); err != ErrorCode::None)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error loadProgram(SaveRestore& helper, Program& program)
|
||||
{
|
||||
std::uint32_t signature{};
|
||||
|
||||
if (auto err = helper.read(&signature, sizeof(signature)); err != Error::None)
|
||||
if (auto err = helper.read(&signature, sizeof(signature)); err != ErrorCode::None)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
if (signature != kZasmSignature)
|
||||
{
|
||||
return Error::SignatureMismatch;
|
||||
return ErrorCode::SignatureMismatch;
|
||||
}
|
||||
|
||||
MachineMode mode{};
|
||||
@@ -382,22 +382,22 @@ namespace zasm
|
||||
Node::Id nextNodeId{};
|
||||
helper >> nextNodeId;
|
||||
|
||||
if (auto err = loadNodes(helper, program); err != Error::None)
|
||||
if (auto err = loadNodes(helper, program); err != ErrorCode::None)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
if (auto err = loadSections(helper, program); err != Error::None)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
if (auto err = loadLabels(helper, program); err != Error::None)
|
||||
if (auto err = loadSections(helper, program); err != ErrorCode::None)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
if (auto err = loadSymbols(helper, program); err != Error::None)
|
||||
if (auto err = loadLabels(helper, program); err != ErrorCode::None)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
if (auto err = loadSymbols(helper, program); err != ErrorCode::None)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
@@ -406,7 +406,7 @@ namespace zasm
|
||||
auto& programState = program.getState();
|
||||
programState.nextNodeId = nextNodeId;
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
zasm::Expected<Program, Error> load(IStream& stream)
|
||||
@@ -416,7 +416,7 @@ namespace zasm
|
||||
SaveRestore helper(stream, true);
|
||||
|
||||
Program program{};
|
||||
if (auto err = loadProgram(helper, program); err != Error::None)
|
||||
if (auto err = loadProgram(helper, program); err != ErrorCode::None)
|
||||
{
|
||||
return makeUnexpected(err);
|
||||
}
|
||||
@@ -434,7 +434,7 @@ namespace zasm
|
||||
FileStream stream(inputFilePath, StreamMode::Read);
|
||||
if (!stream.isOpen())
|
||||
{
|
||||
return makeUnexpected(Error::AccessDenied);
|
||||
return makeUnexpected(Error{ ErrorCode::AccessDenied });
|
||||
}
|
||||
|
||||
return load(stream);
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace zasm
|
||||
{
|
||||
helper << NodeType::Sentinel;
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error saveNode_(SaveRestore& helper, const Program& program, const Label& data)
|
||||
@@ -32,7 +32,7 @@ namespace zasm
|
||||
|
||||
helper << data.getId();
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error saveNode_(SaveRestore& helper, const Program& program, const EmbeddedLabel& data)
|
||||
@@ -43,7 +43,7 @@ namespace zasm
|
||||
helper << data.getRelativeLabel().getId();
|
||||
helper << data.getSize();
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error saveNode_(SaveRestore& helper, const Program& program, const Data& data)
|
||||
@@ -54,7 +54,7 @@ namespace zasm
|
||||
helper << static_cast<std::uint64_t>(data.getRepeatCount());
|
||||
helper.write(data.getData(), data.getSize());
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error saveNode_(SaveRestore& helper, const Program& program, const Section& data)
|
||||
@@ -63,7 +63,7 @@ namespace zasm
|
||||
|
||||
helper << data.getId();
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error saveNode_(SaveRestore& helper, const Program& program, const Align& data)
|
||||
@@ -73,14 +73,14 @@ namespace zasm
|
||||
helper << data.getType();
|
||||
helper << data.getAlign();
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error saveOperand_(SaveRestore& helper, const Operand::None&)
|
||||
{
|
||||
helper << OperandType::None;
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error saveOperand_(SaveRestore& helper, const Reg& data)
|
||||
@@ -89,7 +89,7 @@ namespace zasm
|
||||
|
||||
helper << data.getId();
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error saveOperand_(SaveRestore& helper, const Mem& data)
|
||||
@@ -104,7 +104,7 @@ namespace zasm
|
||||
helper << data.getDisplacement();
|
||||
helper << data.getLabelId();
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error saveOperand_(SaveRestore& helper, const Imm& data)
|
||||
@@ -113,7 +113,7 @@ namespace zasm
|
||||
|
||||
helper << data.value<std::int64_t>();
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error saveOperand_(SaveRestore& helper, const Label& data)
|
||||
@@ -122,7 +122,7 @@ namespace zasm
|
||||
|
||||
helper << data.getId();
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error saveOperand(SaveRestore& helper, const Operand& op)
|
||||
@@ -140,13 +140,13 @@ namespace zasm
|
||||
for (std::size_t i = 0; i < data.getOperandCount(); ++i)
|
||||
{
|
||||
const auto& op = data.getOperand(i);
|
||||
if (auto err = saveOperand(helper, op); err != Error::None)
|
||||
if (auto err = saveOperand(helper, op); err != ErrorCode::None)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error saveNode(SaveRestore& helper, const Program& program, const Node* node)
|
||||
@@ -157,12 +157,12 @@ namespace zasm
|
||||
helper << nodeInt->getUserDataU64();
|
||||
|
||||
auto err = nodeInt->visit([&](const auto& nodeData) { return saveNode_(helper, program, nodeData); });
|
||||
if (err != Error::None)
|
||||
if (err != ErrorCode::None)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error saveNodes(SaveRestore& helper, const Program& program)
|
||||
@@ -174,14 +174,14 @@ namespace zasm
|
||||
const auto* node = program.getHead();
|
||||
while (node != nullptr)
|
||||
{
|
||||
if (auto err = saveNode(helper, program, node); err != Error::None)
|
||||
if (auto err = saveNode(helper, program, node); err != ErrorCode::None)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
node = node->getNext();
|
||||
}
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error saveLabels(SaveRestore& helper, const Program& program)
|
||||
@@ -200,7 +200,7 @@ namespace zasm
|
||||
helper << getNodeId(labelData.node);
|
||||
}
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error saveSections(SaveRestore& helper, const Program& program)
|
||||
@@ -219,7 +219,7 @@ namespace zasm
|
||||
helper << getNodeId(sectionData.node);
|
||||
}
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error saveSymbols(SaveRestore& helper, const Program& program)
|
||||
@@ -228,12 +228,12 @@ namespace zasm
|
||||
const auto& programState = program.getState();
|
||||
const auto& symbols = programState.symbolNames;
|
||||
|
||||
if (auto err = symbols.save(stream); err != Error::None)
|
||||
if (auto err = symbols.save(stream); err != ErrorCode::None)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error saveProgram(SaveRestore& helper, const Program& program)
|
||||
@@ -246,27 +246,27 @@ namespace zasm
|
||||
auto& programState = program.getState();
|
||||
helper << programState.nextNodeId;
|
||||
|
||||
if (auto err = saveNodes(helper, program); err != Error::None)
|
||||
if (auto err = saveNodes(helper, program); err != ErrorCode::None)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
if (auto err = saveSections(helper, program); err != Error::None)
|
||||
if (auto err = saveSections(helper, program); err != ErrorCode::None)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
if (auto err = saveLabels(helper, program); err != Error::None)
|
||||
if (auto err = saveLabels(helper, program); err != ErrorCode::None)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
if (auto err = saveSymbols(helper, program); err != Error::None)
|
||||
if (auto err = saveSymbols(helper, program); err != ErrorCode::None)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
Error save(const Program& program, IStream& stream)
|
||||
@@ -275,12 +275,12 @@ namespace zasm
|
||||
{
|
||||
SaveRestore helper(stream, false);
|
||||
|
||||
if (auto err = saveProgram(helper, program); err != Error::None)
|
||||
if (auto err = saveProgram(helper, program); err != ErrorCode::None)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
catch (Error err)
|
||||
{
|
||||
@@ -293,7 +293,7 @@ namespace zasm
|
||||
FileStream fs(outputFilePath, StreamMode::Write);
|
||||
if (!fs.isOpen())
|
||||
{
|
||||
return Error::AccessDenied;
|
||||
return ErrorCode::AccessDenied;
|
||||
}
|
||||
|
||||
return save(program, fs);
|
||||
|
||||
@@ -33,26 +33,26 @@ namespace zasm
|
||||
{
|
||||
if (_isLoad)
|
||||
{
|
||||
return Error::InvalidOperation;
|
||||
return ErrorCode::InvalidOperation;
|
||||
}
|
||||
_stream.write(src, length);
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
Error read(void* dst, size_t length)
|
||||
{
|
||||
if (!_isLoad || _stream.isEnd())
|
||||
{
|
||||
return Error::InvalidOperation;
|
||||
return ErrorCode::InvalidOperation;
|
||||
}
|
||||
_stream.read(dst, length);
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
template<typename T> SaveRestore& operator<<(const T& value)
|
||||
{
|
||||
if (_isLoad)
|
||||
throw Error::InvalidOperation;
|
||||
throw Error{ ErrorCode::InvalidOperation };
|
||||
|
||||
using ValueType = std::decay_t<T>;
|
||||
|
||||
@@ -60,17 +60,18 @@ namespace zasm
|
||||
|
||||
if constexpr (kEnableVariableLengthEncoding && std::is_integral_v<ValueType>)
|
||||
{
|
||||
if (auto err = writeVariableInteger(value); err != Error::None)
|
||||
if (auto err = writeVariableInteger(value); err != ErrorCode::None)
|
||||
throw err;
|
||||
}
|
||||
else if constexpr (kEnableVariableLengthEncoding && std::is_enum_v<ValueType>)
|
||||
{
|
||||
if (auto err = writeVariableInteger(static_cast<std::underlying_type_t<ValueType>>(value)); err != Error::None)
|
||||
if (auto err = writeVariableInteger(static_cast<std::underlying_type_t<ValueType>>(value));
|
||||
err != ErrorCode::None)
|
||||
throw err;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (auto err = write(&value, sizeof(T)); err != Error::None)
|
||||
if (auto err = write(&value, sizeof(T)); err != ErrorCode::None)
|
||||
throw err;
|
||||
}
|
||||
|
||||
@@ -80,7 +81,7 @@ namespace zasm
|
||||
template<typename T> SaveRestore& operator>>(T& value)
|
||||
{
|
||||
if (!_isLoad)
|
||||
throw Error::InvalidOperation;
|
||||
throw ErrorCode::InvalidOperation;
|
||||
|
||||
using ValueType = std::decay_t<T>;
|
||||
|
||||
@@ -88,7 +89,7 @@ namespace zasm
|
||||
|
||||
if constexpr (kEnableVariableLengthEncoding && std::is_integral_v<ValueType>)
|
||||
{
|
||||
if (auto err = readVariableInteger(value); err != Error::None)
|
||||
if (auto err = readVariableInteger(value); err != ErrorCode::None)
|
||||
throw err;
|
||||
}
|
||||
else if constexpr (kEnableVariableLengthEncoding && std::is_enum_v<ValueType>)
|
||||
@@ -96,14 +97,14 @@ namespace zasm
|
||||
using T2 = std::underlying_type_t<ValueType>;
|
||||
|
||||
T2 tmp{};
|
||||
if (auto err = readVariableInteger(tmp); err != Error::None)
|
||||
if (auto err = readVariableInteger(tmp); err != ErrorCode::None)
|
||||
throw err;
|
||||
|
||||
value = static_cast<T>(tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (auto err = read(static_cast<void*>(&value), sizeof(T)); err != Error::None)
|
||||
if (auto err = read(static_cast<void*>(&value), sizeof(T)); err != ErrorCode::None)
|
||||
throw err;
|
||||
}
|
||||
|
||||
@@ -125,10 +126,10 @@ namespace zasm
|
||||
}
|
||||
tempBuffer[bytesUsed++] = static_cast<std::uint8_t>(tmp & 0x7F);
|
||||
|
||||
if (auto err = write(tempBuffer, bytesUsed); err != Error::None)
|
||||
if (auto err = write(tempBuffer, bytesUsed); err != ErrorCode::None)
|
||||
return err;
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
template<typename T> Error readVariableInteger(T& value)
|
||||
@@ -137,7 +138,7 @@ namespace zasm
|
||||
for (std::size_t i = 0;; i++)
|
||||
{
|
||||
std::uint8_t byte;
|
||||
if (auto err = read(&byte, sizeof(byte)); err != Error::None)
|
||||
if (auto err = read(&byte, sizeof(byte)); err != ErrorCode::None)
|
||||
return err;
|
||||
|
||||
tmp |= (static_cast<T>(byte) & 0x7F) << (i * 7);
|
||||
@@ -145,7 +146,7 @@ namespace zasm
|
||||
break;
|
||||
}
|
||||
value = static_cast<T>(tmp);
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "../program/program.state.hpp"
|
||||
#include "zasm/core/math.hpp"
|
||||
#include "zasm/encoder/encoder.hpp"
|
||||
#include "zasm/formatter/formatter.hpp"
|
||||
|
||||
#include <Zydis/Decoder.h>
|
||||
#include <algorithm>
|
||||
@@ -66,7 +67,7 @@ namespace zasm
|
||||
nodeEntry.address = ctx.va;
|
||||
ctx.nodeIndex++;
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static constexpr auto kX86NopTable = std::array<std::array<std::uint8_t, 8>, 9>{ {
|
||||
@@ -140,7 +141,7 @@ namespace zasm
|
||||
ctx.va += alignSize;
|
||||
ctx.offset += alignSize;
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error serializeNode(const detail::ProgramState& prog, SerializeContext& state, const Instruction& instr)
|
||||
@@ -157,7 +158,7 @@ namespace zasm
|
||||
auto& nodeEntry = ctx.nodes[ctx.nodeIndex];
|
||||
ctx.nodeIndex++;
|
||||
|
||||
if (nodeEntry.length != 0 && res->buffer.length != nodeEntry.length)
|
||||
if (nodeEntry.length != 0 && res->buffer.length != nodeEntry.length)
|
||||
{
|
||||
ctx.needsExtraPass = true;
|
||||
}
|
||||
@@ -178,14 +179,14 @@ namespace zasm
|
||||
auto& buffer = state.buffer;
|
||||
buffer.insert(buffer.end(), std::begin(res->buffer.data), std::begin(res->buffer.data) + res->buffer.length);
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error serializeNode(const detail::ProgramState& prog, SerializeContext& state, const Label& label)
|
||||
{
|
||||
if (!label.isValid())
|
||||
{
|
||||
return Error::InvalidLabel;
|
||||
return ErrorCode::InvalidLabel;
|
||||
}
|
||||
|
||||
auto& ctx = state.ctx;
|
||||
@@ -200,14 +201,14 @@ namespace zasm
|
||||
const auto labelIdx = static_cast<std::size_t>(label.getId());
|
||||
if (labelIdx >= prog.labels.size())
|
||||
{
|
||||
return Error::LabelNotFound;
|
||||
return ErrorCode::LabelNotFound;
|
||||
}
|
||||
|
||||
auto& linkEntry = state.ctx.getOrCreateLabelLink(label.getId());
|
||||
linkEntry.boundOffset = ctx.offset;
|
||||
linkEntry.boundVA = ctx.va;
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static bool isSameSection(const EncoderSection& lhs, const EncoderSection& rhs) noexcept
|
||||
@@ -235,7 +236,7 @@ namespace zasm
|
||||
const auto sectionIndex = static_cast<std::size_t>(section.getId());
|
||||
if (sectionIndex >= prog.sections.size())
|
||||
{
|
||||
return Error::SectionNotFound;
|
||||
return ErrorCode::SectionNotFound;
|
||||
}
|
||||
|
||||
const auto& sectionData = prog.sections[sectionIndex];
|
||||
@@ -269,7 +270,7 @@ namespace zasm
|
||||
nodeEntry.offset = ctx.offset;
|
||||
nodeEntry.address = ctx.va;
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error serializeNode([[maybe_unused]] const detail::ProgramState& program, SerializeContext& state, const Data& data)
|
||||
@@ -301,7 +302,7 @@ namespace zasm
|
||||
std::copy_n(ptr, dataSize, std::back_inserter(buffer));
|
||||
}
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
static Error serializeNode(const detail::ProgramState& program, SerializeContext& state, const EmbeddedLabel& data)
|
||||
@@ -345,7 +346,7 @@ namespace zasm
|
||||
{
|
||||
if (!ctx.needsExtraPass && absValue >= std::numeric_limits<std::uint8_t>::max())
|
||||
{
|
||||
return Error::InvalidLabel;
|
||||
return ErrorCode::InvalidLabel;
|
||||
}
|
||||
const auto rawValue = static_cast<std::int8_t>(labelAddr);
|
||||
std::memcpy(tempBuf.data(), &rawValue, sizeof(rawValue));
|
||||
@@ -355,7 +356,7 @@ namespace zasm
|
||||
{
|
||||
if (!ctx.needsExtraPass && absValue >= std::numeric_limits<std::uint16_t>::max())
|
||||
{
|
||||
return Error::InvalidLabel;
|
||||
return ErrorCode::InvalidLabel;
|
||||
}
|
||||
const auto rawValue = static_cast<std::int16_t>(labelAddr);
|
||||
std::memcpy(tempBuf.data(), &rawValue, sizeof(rawValue));
|
||||
@@ -365,7 +366,7 @@ namespace zasm
|
||||
{
|
||||
if (!ctx.needsExtraPass && absValue >= std::numeric_limits<std::uint32_t>::max())
|
||||
{
|
||||
return Error::InvalidLabel;
|
||||
return ErrorCode::InvalidLabel;
|
||||
}
|
||||
const auto rawValue = static_cast<std::int32_t>(labelAddr);
|
||||
std::memcpy(tempBuf.data(), &rawValue, sizeof(rawValue));
|
||||
@@ -379,7 +380,7 @@ namespace zasm
|
||||
}
|
||||
else
|
||||
{
|
||||
return Error::InvalidOperation;
|
||||
return ErrorCode::InvalidOperation;
|
||||
}
|
||||
|
||||
auto& nodeEntry = ctx.nodes[ctx.nodeIndex];
|
||||
@@ -406,7 +407,7 @@ namespace zasm
|
||||
auto& buffer = state.buffer;
|
||||
buffer.insert(buffer.end(), std::begin(tempBuf), std::begin(tempBuf) + byteSize);
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
Serializer::Serializer()
|
||||
@@ -476,7 +477,7 @@ namespace zasm
|
||||
defaultSect.address = newBase;
|
||||
defaultSect.nameId = programState.symbolNames.aquire(".text");
|
||||
|
||||
const auto serializePass = [&]() {
|
||||
const auto serializePass = [&]() -> Error {
|
||||
state.buffer.clear();
|
||||
|
||||
encoderCtx.needsExtraPass = false;
|
||||
@@ -485,7 +486,6 @@ namespace zasm
|
||||
encoderCtx.va = newBase;
|
||||
encoderCtx.nodeIndex = 0;
|
||||
encoderCtx.sectionIndex = 0;
|
||||
|
||||
|
||||
// Setup default section.
|
||||
encoderCtx.sections.clear();
|
||||
@@ -494,9 +494,17 @@ namespace zasm
|
||||
for (const auto* node = first; node != lastNode; node = node->getNext())
|
||||
{
|
||||
const auto status = node->visit([&](auto&& n) { return serializeNode(programState, state, n); });
|
||||
if (status != Error::None)
|
||||
if (status != ErrorCode::None)
|
||||
{
|
||||
return status;
|
||||
const auto fmtOptions = formatter::Options::HexImmediates | formatter::Options::HexOffsets;
|
||||
const auto nodeString = formatter::toString(program, node, fmtOptions);
|
||||
|
||||
char msg[256];
|
||||
std::snprintf(
|
||||
msg, sizeof(msg), "Error at node \"%s\" with id %u: %s", nodeString.c_str(),
|
||||
static_cast<std::uint32_t>(node->getId()), status.getErrorMessage());
|
||||
|
||||
return Error(status.getCode(), msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -504,11 +512,11 @@ namespace zasm
|
||||
codeDiff = newSize - codeSize;
|
||||
codeSize = newSize;
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
};
|
||||
|
||||
// Initial.
|
||||
if (const auto status = serializePass(); status != Error::None)
|
||||
if (const auto status = serializePass(); status != ErrorCode::None)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
@@ -521,13 +529,13 @@ namespace zasm
|
||||
std::begin(encoderCtx.labelLinks), std::end(encoderCtx.labelLinks), isUnresolvedLabel);
|
||||
if (hasUnresolvedLinks)
|
||||
{
|
||||
return Error::UnresolvedLabel;
|
||||
return ErrorCode::UnresolvedLabel;
|
||||
}
|
||||
|
||||
// Second or more passes.
|
||||
while (encoderCtx.needsExtraPass)
|
||||
{
|
||||
if (const auto status = serializePass(); status != Error::None)
|
||||
if (const auto status = serializePass(); status != ErrorCode::None)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
@@ -543,7 +551,7 @@ namespace zasm
|
||||
const auto labelIdx = static_cast<std::size_t>(labelLink.id);
|
||||
if (labelIdx >= programState.labels.size())
|
||||
{
|
||||
return Error::InvalidLabel;
|
||||
return ErrorCode::InvalidLabel;
|
||||
}
|
||||
|
||||
auto& labelEntry = _state->labels.emplace_back();
|
||||
@@ -565,12 +573,12 @@ namespace zasm
|
||||
decoderStatus = ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZydisStackWidth::ZYDIS_STACK_WIDTH_64);
|
||||
break;
|
||||
default:
|
||||
return Error::InvalidParameter;
|
||||
return ErrorCode::InvalidParameter;
|
||||
}
|
||||
if (decoderStatus != ZYAN_STATUS_SUCCESS)
|
||||
{
|
||||
// FIXME: Make this a better error.
|
||||
return Error::InvalidMode;
|
||||
return ErrorCode::InvalidMode;
|
||||
}
|
||||
|
||||
_state->relocations.clear();
|
||||
@@ -607,7 +615,7 @@ namespace zasm
|
||||
if (decoderStatus != ZYAN_STATUS_SUCCESS)
|
||||
{
|
||||
// FIXME: Properly translate the error.
|
||||
return Error::ImpossibleRelocation;
|
||||
return ErrorCode::ImpossibleRelocation;
|
||||
}
|
||||
|
||||
if (node.relocData == RelocationData::Immediate)
|
||||
@@ -676,14 +684,14 @@ namespace zasm
|
||||
|
||||
_state->base = newBase;
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
Error Serializer::relocate(std::int64_t newBase)
|
||||
{
|
||||
if (_state->code.empty())
|
||||
{
|
||||
return Error::EmptyState;
|
||||
return ErrorCode::EmptyState;
|
||||
}
|
||||
|
||||
const auto oldBase = _state->base;
|
||||
@@ -706,7 +714,7 @@ namespace zasm
|
||||
|
||||
if (newValue > std::numeric_limits<std::uint32_t>::max())
|
||||
{
|
||||
return Error::ImpossibleRelocation;
|
||||
return ErrorCode::ImpossibleRelocation;
|
||||
}
|
||||
|
||||
value = static_cast<std::uint32_t>(newValue);
|
||||
@@ -761,7 +769,7 @@ namespace zasm
|
||||
_state->externalRelocations = std::move(externalRelocs);
|
||||
_state->base = newBase;
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
std::int64_t Serializer::getBase() const noexcept
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace zasm::x86
|
||||
|
||||
_cursor = _program.insertAfter(_cursor, labelNode.value());
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
Error Assembler::section(
|
||||
@@ -62,7 +62,7 @@ namespace zasm::x86
|
||||
|
||||
_cursor = _program.insertAfter(_cursor, sectNode.value());
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
Error Assembler::db(std::uint8_t val, std::size_t repeatCount /*= 1*/)
|
||||
@@ -72,7 +72,7 @@ namespace zasm::x86
|
||||
auto* dataNode = _program.createNode(std::move(data));
|
||||
_cursor = _program.insertAfter(_cursor, dataNode);
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
Error Assembler::dw(std::uint16_t val, std::size_t repeatCount /*= 1*/)
|
||||
@@ -82,7 +82,7 @@ namespace zasm::x86
|
||||
auto* dataNode = _program.createNode(std::move(data));
|
||||
_cursor = _program.insertAfter(_cursor, dataNode);
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
Error Assembler::dd(std::uint32_t val, std::size_t repeatCount /*= 1*/)
|
||||
@@ -92,7 +92,7 @@ namespace zasm::x86
|
||||
auto* dataNode = _program.createNode(std::move(data));
|
||||
_cursor = _program.insertAfter(_cursor, dataNode);
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
Error Assembler::dq(std::uint64_t val, std::size_t repeatCount /*= 1*/)
|
||||
@@ -102,7 +102,7 @@ namespace zasm::x86
|
||||
auto* dataNode = _program.createNode(std::move(data));
|
||||
_cursor = _program.insertAfter(_cursor, dataNode);
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
Error Assembler::embed(const void* ptr, std::size_t len)
|
||||
@@ -112,7 +112,7 @@ namespace zasm::x86
|
||||
auto* dataNode = _program.createNode(std::move(data));
|
||||
_cursor = _program.insertAfter(_cursor, dataNode);
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
Error Assembler::align(Align::Type type, std::uint32_t align)
|
||||
@@ -122,7 +122,7 @@ namespace zasm::x86
|
||||
auto* node = _program.createNode(std::move(data));
|
||||
_cursor = _program.insertAfter(_cursor, node);
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
Error Assembler::emit(Instruction::Attribs attribs, Instruction::Mnemonic mnemonic, std::size_t numOps, const Operand* ops)
|
||||
@@ -136,7 +136,7 @@ namespace zasm::x86
|
||||
auto* node = _program.createNode(std::move(instr));
|
||||
_cursor = _program.insertAfter(_cursor, node);
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
Error Assembler::emit(const Instruction& instr)
|
||||
@@ -158,13 +158,13 @@ namespace zasm::x86
|
||||
}
|
||||
else
|
||||
{
|
||||
return Error::InvalidMode;
|
||||
return ErrorCode::InvalidMode;
|
||||
}
|
||||
|
||||
auto* node = _program.createNode(EmbeddedLabel(label, size));
|
||||
_cursor = _program.insertAfter(_cursor, node);
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
Error Assembler::embedLabelRel(Label label, Label relativeTo, BitSize size)
|
||||
@@ -172,7 +172,7 @@ namespace zasm::x86
|
||||
auto* node = _program.createNode(EmbeddedLabel(label, relativeTo, size));
|
||||
_cursor = _program.insertAfter(_cursor, node);
|
||||
|
||||
return Error::None;
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
void Assembler::onNodeDetach(Node* node) noexcept
|
||||
|
||||
Reference in New Issue
Block a user