The Pedigree Project 0.1
UserReturnFrame.h
1/* Copyright (c) 2026, Pedigree Developers. */
2#ifndef KERNEL_PROCESSOR_USER_RETURN_FRAME_H
3#define KERNEL_PROCESSOR_USER_RETURN_FRAME_H
4
5#include "pedigree/kernel/compiler.h"
6#include "pedigree/kernel/processor/state_forward.h"
7#include "pedigree/kernel/processor/types.h"
8
9class Thread;
10
12 uint64_t r15, r14, r13, r12, rbp, rbx, r11, r10, r9, r8;
13 uint64_t rax, rcx, rdx, rsi, rdi, orig_rax, rip;
14 uint64_t cs, eflags, rsp, ss, fs_base, gs_base, ds, es, fs, gs;
15};
16
17static_assert(sizeof(Amd64UserRegisters) == 27 * sizeof(uint64_t), "amd64 register count");
18static_assert(sizeof(Amd64UserRegisters) == 216, "amd64 NT_PRSTATUS payload size");
19static_assert(__builtin_offsetof(Amd64UserRegisters, orig_rax) == 120, "orig_rax ABI offset");
20static_assert(__builtin_offsetof(Amd64UserRegisters, rip) == 128, "rip ABI offset");
21static_assert(__builtin_offsetof(Amd64UserRegisters, fs_base) == 168, "fs_base ABI offset");
22static_assert(__builtin_offsetof(Amd64UserRegisters, gs) == 208, "last register ABI offset");
23
25 enum class Architecture : uint64_t { Unavailable, Amd64 };
26 Architecture architecture = Architecture::Unavailable;
27 // Only this payload is the amd64 ABI, not the architecture tag or wrapper.
28 Amd64UserRegisters amd64{};
29};
30
31class EXPORTED_PUBLIC UserReturnFrame {
32 friend class Thread;
33 friend class PerProcessorScheduler;
34
35 public:
36 enum class Origin { Syscall, Interrupt, SignalRestore, NewImage };
37
38 // The source must come from a metadata-aware entry or synthetic-frame path.
39 UserReturnFrame(Thread& owner, const SyscallState& state, Origin origin = Origin::Syscall)
40 : m_Owner(&owner), m_Origin(origin), m_Syscall(&state), m_Interrupt(nullptr) {}
41 UserReturnFrame(Thread& owner, const InterruptState& state, Origin origin = Origin::Interrupt)
42 : m_Owner(&owner), m_Origin(origin), m_Syscall(nullptr), m_Interrupt(&state) {}
43
44 UserReturnFrame(const UserReturnFrame&) = delete;
45 UserReturnFrame& operator=(const UserReturnFrame&) = delete;
47 UserReturnFrame& operator=(UserReturnFrame&&) = delete;
48
49 Origin origin() const {
50 return m_Origin;
51 }
52
53 // Requires the owning Thread's active lexical frame scope. Failure leaves
54 // output unchanged; no live state pointer or partial register set escapes.
55 bool snapshot(UserRegisterSnapshot& output) const;
56
57 private:
58 Thread* const m_Owner;
59 const Origin m_Origin;
60 const SyscallState* const m_Syscall;
61 const InterruptState* const m_Interrupt;
62 bool m_Terminal = false;
63};
64
65#endif