TPDE
Loading...
Searching...
No Matches
FunctionWriterX64.hpp
1// SPDX-FileCopyrightText: 2025 Contributors to TPDE <https://tpde.org>
2// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3#pragma once
4
5#include "tpde/FunctionWriter.hpp"
6#include "tpde/base.hpp"
7#include <fadec-enc2.h>
8
9namespace tpde::x64 {
10
11/// Helper class to write function text for X64.
12class FunctionWriterX64 : public FunctionWriter<FunctionWriterX64> {
13 friend class FunctionWriter<FunctionWriterX64>;
14
15public:
16 void align(size_t align) noexcept {
17 u32 old_off = offset();
18 FunctionWriter::align(align);
19 // Pad text section with NOPs.
20 if (u32 cur_off = offset(); cur_off > old_off) {
21 fe64_NOP(cur_ptr() - (cur_off - old_off), cur_off - old_off);
22 }
23 }
24
25private:
26 void handle_fixups() noexcept;
27};
28
29inline void FunctionWriterX64::handle_fixups() noexcept {
30 for (const LabelFixup &fixup : label_fixups) {
31 u32 label_off = label_offset(fixup.label);
32 u8 *dst_ptr = begin_ptr() + fixup.off;
33 switch (fixup.kind) {
34 case LabelFixupKind::X64_JMP_OR_MEM_DISP: {
35 // fix the jump immediate
36 u32 value = (label_off - fixup.off) - 4;
37 std::memcpy(dst_ptr, &value, sizeof(u32));
38 break;
39 }
40 case LabelFixupKind::X64_JUMP_TABLE: {
41 const auto table_off = *reinterpret_cast<u32 *>(dst_ptr);
42 const auto diff = (i32)label_off - (i32)table_off;
43 std::memcpy(dst_ptr, &diff, sizeof(u32));
44 break;
45 }
46 default: TPDE_UNREACHABLE("unexpected label fixup kind");
47 }
48 }
49}
50
51} // namespace tpde::x64
util::SmallVector< LabelFixup > label_fixups
Helper class to write function text for X64.