From 41b2975cf7e753ec10a5f3188cfa26ea6c876282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Mon, 29 Apr 2024 01:15:04 +0300 Subject: [PATCH 1/2] Don't compute an address with a temporary displacement --- src/zasm/src/encoder/encoder.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/zasm/src/encoder/encoder.cpp b/src/zasm/src/encoder/encoder.cpp index 1be2257..d873216 100644 --- a/src/zasm/src/encoder/encoder.cpp +++ b/src/zasm/src/encoder/encoder.cpp @@ -323,6 +323,7 @@ namespace zasm bool usingLabel = false; bool externalLabel = false; + bool isDisplacementValid = true; if (const auto labelId = src.getLabelId(); labelId != Label::Id::Invalid) { @@ -338,6 +339,7 @@ namespace zasm else { displacement += kTemporaryRel32Value; + isDisplacementValid = false; if (!externalLabel) { ctx->needsExtraPass = true; @@ -346,7 +348,8 @@ namespace zasm } else { - displacement += kTemporaryRel32Value; + displacement = kTemporaryRel32Value; + isDisplacementValid = false; } usingLabel = true; } @@ -378,7 +381,10 @@ namespace zasm } else { - displacement = displacement - (address + instrSize); + if (isDisplacementValid) + { + displacement = displacement - (address + instrSize); + } } if (externalLabel) From e365cce154e7f1ef8cc61473a5805d01480afe73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Mon, 29 Apr 2024 01:15:46 +0300 Subject: [PATCH 2/2] Add new test to cover the address calculation issue --- src/tests/tests/tests.serialization.cpp | 31 +++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/tests/tests/tests.serialization.cpp b/src/tests/tests/tests.serialization.cpp index 458c714..c15f7d1 100644 --- a/src/tests/tests/tests.serialization.cpp +++ b/src/tests/tests/tests.serialization.cpp @@ -1161,4 +1161,35 @@ namespace zasm::tests ASSERT_EQ(serializer.getLabelAddress(label03.getId()), 0x0000000000401000); } + TEST(SerializationTests, TestBasicLea) + { + Program program(MachineMode::AMD64); + + 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); + + Serializer serializer; + ASSERT_EQ(serializer.serialize(program, 0x140015000), Error::None); + + const std::array expected = { + 0x55, 0x48, 0x8D, 0x2D, 0x05, 0x00, 0x00, 0x00, 0x48, 0x87, 0x2C, 0x24, 0xC3, + }; + ASSERT_EQ(serializer.getCodeSize(), expected.size()); + + const auto* data = serializer.getCode(); + ASSERT_NE(data, nullptr); + for (std::size_t i = 0; i < expected.size(); i++) + { + ASSERT_EQ(data[i], expected[i]); + } + + ASSERT_EQ(serializer.getLabelAddress(label.getId()), 0x140015000 + 13); + } + } // namespace zasm::tests