TPDE
Loading...
Searching...
No Matches
AssemblerElfX64.hpp
1// SPDX-FileCopyrightText: 2025 Contributors to TPDE <https://tpde.org>
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4#pragma once
5
6#include "tpde/AssemblerElf.hpp"
7#include <fadec-enc2.h>
8
9namespace tpde::x64 {
10
11/// The x86_64-specific implementation for the AssemblerElf
12struct AssemblerElfX64 : AssemblerElf<AssemblerElfX64> {
14
15 static const TargetInfo TARGET_INFO;
16
17 class SectionWriter : public Base::SectionWriterBase<SectionWriter> {
18 public:
19 void align(size_t align) noexcept;
20 };
21
22 enum class UnresolvedEntryKind : u8 {
23 JMP_OR_MEM_DISP,
24 JUMP_TABLE,
25 };
26
27 explicit AssemblerElfX64() = default;
28
29 void add_unresolved_entry(Label label,
30 SecRef sec,
31 u32 off,
32 UnresolvedEntryKind kind) noexcept {
33 AssemblerElfBase::reloc_sec(sec, label, static_cast<u8>(kind), off);
34 }
35
36 void handle_fixup(const TempSymbolInfo &info,
37 const TempSymbolFixup &fixup) noexcept;
38};
39
40inline void
41 AssemblerElfX64::handle_fixup(const TempSymbolInfo &info,
42 const TempSymbolFixup &fixup) noexcept {
43 // TODO: emit relocations when fixup is in different section
44 assert(info.section == fixup.section && "multi-text section not supported");
45 u8 *dst_ptr = get_section(fixup.section).data.data() + fixup.off;
46
47 switch (static_cast<UnresolvedEntryKind>(fixup.kind)) {
48 case UnresolvedEntryKind::JMP_OR_MEM_DISP: {
49 // fix the jump immediate
50 u32 value = (info.off - fixup.off) - 4;
51 std::memcpy(dst_ptr, &value, sizeof(u32));
52 break;
53 }
54 case UnresolvedEntryKind::JUMP_TABLE: {
55 const auto table_off = *reinterpret_cast<u32 *>(dst_ptr);
56 const auto diff = (i32)info.off - (i32)table_off;
57 std::memcpy(dst_ptr, &diff, sizeof(u32));
58 break;
59 }
60 }
61}
62
63inline void AssemblerElfX64::SectionWriter::align(size_t align) noexcept {
64 u32 old_off = offset();
65 SectionWriterBase::align(align);
66 // Pad text section with NOPs.
67 if (u32 cur_off = offset(); cur_off > old_off) {
68 fe64_NOP(cur_ptr() - (cur_off - old_off), cur_off - old_off);
69 }
70}
71
72} // namespace tpde::x64
AssemblerElf contains the architecture-independent logic to emit ELF object files (currently linux-sp...
The x86_64-specific implementation for the AssemblerElf.