Everywhere: Make the codebase more architecture aware

This commit is contained in:
Undefine 2022-07-22 20:48:24 +02:00 committed by Brian Gianforcaro
parent 6c4b5775e1
commit 97cc33ca47
22 changed files with 108 additions and 36 deletions

View file

@ -85,8 +85,10 @@ ErrorOr<void> Coredump::write_elf_header()
elf_file_header.e_ident[EI_MAG3] = 'F';
#if ARCH(I386)
elf_file_header.e_ident[EI_CLASS] = ELFCLASS32;
#else
#elif ARCH(X86_64) || ARCH(AARCH64)
elf_file_header.e_ident[EI_CLASS] = ELFCLASS64;
#else
# error Unknown architecture
#endif
elf_file_header.e_ident[EI_DATA] = ELFDATA2LSB;
elf_file_header.e_ident[EI_VERSION] = EV_CURRENT;
@ -101,8 +103,12 @@ ErrorOr<void> Coredump::write_elf_header()
elf_file_header.e_type = ET_CORE;
#if ARCH(I386)
elf_file_header.e_machine = EM_386;
#else
#elif ARCH(X86_64)
elf_file_header.e_machine = EM_X86_64;
#elif ARCH(AARCH64)
elf_file_header.e_machine = EM_AARCH64;
#else
# error Unknown architecture
#endif
elf_file_header.e_version = 1;
elf_file_header.e_entry = 0;

View file

@ -20,8 +20,10 @@
#if ARCH(I386)
static constexpr size_t CHUNK_SIZE = 32;
#else
#elif ARCH(X86_64) || ARCH(AARCH64)
static constexpr size_t CHUNK_SIZE = 64;
#else
# error Unknown architecture
#endif
static_assert(is_power_of_two(CHUNK_SIZE));

View file

@ -191,8 +191,10 @@ RefPtr<Process> Process::create_kernel_process(RefPtr<Thread>& first_thread, Non
first_thread->regs().set_ip((FlatPtr)entry);
#if ARCH(I386)
first_thread->regs().esp = FlatPtr(entry_data); // entry function argument is expected to be in regs.esp
#else
#elif ARCH(X86_64)
first_thread->regs().rdi = FlatPtr(entry_data); // entry function argument is expected to be in regs.rdi
#else
# error Unknown architecture
#endif
if (do_register == RegisterProcess::Yes)

View file

@ -149,10 +149,12 @@ static ErrorOr<FlatPtr> make_userspace_context_for_main_thread([[maybe_unused]]
push_on_new_stack(envp);
push_on_new_stack(argv);
push_on_new_stack(argv_entries.size());
#else
#elif ARCH(X86_64)
regs.rdi = argv_entries.size();
regs.rsi = argv;
regs.rdx = envp;
#else
# error Unknown architecture
#endif
VERIFY(new_sp % 16 == 0);

View file

@ -89,7 +89,7 @@ ErrorOr<FlatPtr> Process::sys$fork(RegisterState& regs)
dbgln_if(FORK_DEBUG, "fork: child will begin executing at {:#04x}:{:p} with stack {:#04x}:{:p}, kstack {:#04x}:{:p}",
child_regs.cs, child_regs.eip, child_regs.ss, child_regs.esp, child_regs.ss0, child_regs.esp0);
#else
#elif ARCH(X86_64)
auto& child_regs = child_first_thread->m_regs;
child_regs.rax = 0; // fork() returns 0 in the child :^)
child_regs.rbx = regs.rbx;
@ -113,6 +113,8 @@ ErrorOr<FlatPtr> Process::sys$fork(RegisterState& regs)
dbgln_if(FORK_DEBUG, "fork: child will begin executing at {:#04x}:{:p} with stack {:p}, kstack {:p}",
child_regs.cs, child_regs.rip, child_regs.rsp, child_regs.rsp0);
#else
# error Unknown architecture
#endif
{

View file

@ -19,8 +19,12 @@ ErrorOr<FlatPtr> Process::sys$uname(Userspace<utsname*> user_buf)
memcpy(buf.version, "FIXME", 6);
#if ARCH(I386)
memcpy(buf.machine, "i686", 5);
#else
#elif ARCH(X86_64)
memcpy(buf.machine, "x86_64", 7);
#elif ARCH(AARCH64)
memcpy(buf.machine, "AArch64", 7);
#else
# error Unknown architecture
#endif
hostname().with_shared([&](auto const& name) {

View file

@ -96,11 +96,13 @@ Thread::Thread(NonnullRefPtr<Process> process, NonnullOwnPtr<Memory::Region> ker
m_regs.ss = GDT_SELECTOR_DATA3 | 3;
m_regs.gs = GDT_SELECTOR_TLS | 3;
}
#else
#elif ARCH(X86_64)
if (m_process->is_kernel_process())
m_regs.cs = GDT_SELECTOR_CODE0;
else
m_regs.cs = GDT_SELECTOR_CODE3 | 3;
#else
# error Unknown architecture
#endif
m_regs.cr3 = m_process->address_space().page_directory().cr3();

View file

@ -93,7 +93,7 @@ static u64 read_register_safe64(HPETRegister const& reg)
{
#if ARCH(X86_64)
return reg.full;
#else
#elif ARCH(I386)
// As per 2.4.7 this reads the 64 bit value in a consistent manner
// using only 32 bit reads
u32 low, high = reg.high;
@ -105,6 +105,8 @@ static u64 read_register_safe64(HPETRegister const& reg)
high = new_high;
}
return ((u64)high << 32) | (u64)low;
#else
# error Unknown architecture
#endif
}

View file

@ -219,9 +219,11 @@ int main(int argc, char** argv)
#if ARCH(I386)
asm volatile("mov %%eax, %%esp" ::"a"(bad_esp));
asm volatile("pushl $0");
#else
#elif ARCH(X86_64)
asm volatile("movq %%rax, %%rsp" ::"a"(bad_esp));
asm volatile("pushq $0");
#else
# error Unknown architecture
#endif
return Crash::Failure::DidNotCrash;

View file

@ -114,12 +114,14 @@ static TitleAndText build_cpu_registers(const ELF::Core::ThreadInfo& thread_info
builder.appendff("eax={:p} ebx={:p} ecx={:p} edx={:p}\n", regs.eax, regs.ebx, regs.ecx, regs.edx);
builder.appendff("ebp={:p} esp={:p} esi={:p} edi={:p}\n", regs.ebp, regs.esp, regs.esi, regs.edi);
builder.appendff("eip={:p} eflags={:p}", regs.eip, regs.eflags);
#else
#elif ARCH(X86_64)
builder.appendff("rax={:p} rbx={:p} rcx={:p} rdx={:p}\n", regs.rax, regs.rbx, regs.rcx, regs.rdx);
builder.appendff("rbp={:p} rsp={:p} rsi={:p} rdi={:p}\n", regs.rbp, regs.rsp, regs.rsi, regs.rdi);
builder.appendff(" r8={:p} r9={:p} r10={:p} r11={:p}\n", regs.r8, regs.r9, regs.r10, regs.r11);
builder.appendff("r12={:p} r13={:p} r14={:p} r15={:p}\n", regs.r12, regs.r13, regs.r14, regs.r15);
builder.appendff("rip={:p} rflags={:p}", regs.rip, regs.rflags);
#else
# error Unknown architecture
#endif
return {

View file

@ -43,12 +43,14 @@ static void handle_print_registers(PtraceRegisters const& regs)
outln("eax={:p} ebx={:p} ecx={:p} edx={:p}", regs.eax, regs.ebx, regs.ecx, regs.edx);
outln("esp={:p} ebp={:p} esi={:p} edi={:p}", regs.esp, regs.ebp, regs.esi, regs.edi);
outln("eip={:p} eflags={:p}", regs.eip, regs.eflags);
#else
#elif ARCH(X86_64)
outln("rax={:p} rbx={:p} rcx={:p} rdx={:p}", regs.rax, regs.rbx, regs.rcx, regs.rdx);
outln("rsp={:p} rbp={:p} rsi={:p} rdi={:p}", regs.rsp, regs.rbp, regs.rsi, regs.rdi);
outln("r8 ={:p} r9 ={:p} r10={:p} r11={:p}", regs.r8, regs.r9, regs.r10, regs.r11);
outln("r12={:p} r13={:p} r14={:p} r15={:p}", regs.r12, regs.r13, regs.r14, regs.r15);
outln("rip={:p} rflags={:p}", regs.rip, regs.rflags);
#else
# error Unknown architecture
#endif
}
@ -246,8 +248,10 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
const PtraceRegisters& regs = optional_regs.value();
#if ARCH(I386)
const FlatPtr ip = regs.eip;
#else
#elif ARCH(X86_64)
const FlatPtr ip = regs.rip;
#else
# error Unknown architecture
#endif
auto symbol_at_ip = g_debug_session->symbolicate(ip);

View file

@ -12,7 +12,8 @@ namespace HackStudio {
RegistersModel::RegistersModel(PtraceRegisters const& regs)
: m_raw_registers(regs)
{
#if ARCH(I386)
#if ARCH(I386) || ARCH(X86_64)
# if ARCH(I386)
m_registers.append({ "eax", regs.eax });
m_registers.append({ "ebx", regs.ebx });
m_registers.append({ "ecx", regs.ecx });
@ -23,7 +24,7 @@ RegistersModel::RegistersModel(PtraceRegisters const& regs)
m_registers.append({ "edi", regs.edi });
m_registers.append({ "eip", regs.eip });
m_registers.append({ "eflags", regs.eflags });
#else
# else
m_registers.append({ "rax", regs.rax });
m_registers.append({ "rbx", regs.rbx });
m_registers.append({ "rcx", regs.rcx });
@ -42,7 +43,7 @@ RegistersModel::RegistersModel(PtraceRegisters const& regs)
m_registers.append({ "r14", regs.r14 });
m_registers.append({ "r15", regs.r15 });
m_registers.append({ "rflags", regs.rflags });
#endif
# endif
m_registers.append({ "cs", regs.cs });
m_registers.append({ "ss", regs.ss });
@ -50,12 +51,16 @@ RegistersModel::RegistersModel(PtraceRegisters const& regs)
m_registers.append({ "es", regs.es });
m_registers.append({ "fs", regs.fs });
m_registers.append({ "gs", regs.gs });
#else
# error Unknown architecture
#endif
}
RegistersModel::RegistersModel(PtraceRegisters const& current_regs, PtraceRegisters const& previous_regs)
: m_raw_registers(current_regs)
{
#if ARCH(I386)
#if ARCH(I386) || ARCH(X86_64)
# if ARCH(I386)
m_registers.append({ "eax", current_regs.eax, current_regs.eax != previous_regs.eax });
m_registers.append({ "ebx", current_regs.ebx, current_regs.ebx != previous_regs.ebx });
m_registers.append({ "ecx", current_regs.ecx, current_regs.ecx != previous_regs.ecx });
@ -66,7 +71,7 @@ RegistersModel::RegistersModel(PtraceRegisters const& current_regs, PtraceRegist
m_registers.append({ "edi", current_regs.edi, current_regs.edi != previous_regs.edi });
m_registers.append({ "eip", current_regs.eip, current_regs.eip != previous_regs.eip });
m_registers.append({ "eflags", current_regs.eflags, current_regs.eflags != previous_regs.eflags });
#else
# else
m_registers.append({ "rax", current_regs.rax, current_regs.rax != previous_regs.rax });
m_registers.append({ "rbx", current_regs.rbx, current_regs.rbx != previous_regs.rbx });
m_registers.append({ "rcx", current_regs.rcx, current_regs.rcx != previous_regs.rcx });
@ -85,13 +90,16 @@ RegistersModel::RegistersModel(PtraceRegisters const& current_regs, PtraceRegist
m_registers.append({ "r14", current_regs.r14, current_regs.r14 != previous_regs.r14 });
m_registers.append({ "r15", current_regs.r15, current_regs.r15 != previous_regs.r15 });
m_registers.append({ "rflags", current_regs.rflags, current_regs.rflags != previous_regs.rflags });
#endif
# endif
m_registers.append({ "cs", current_regs.cs, current_regs.cs != previous_regs.cs });
m_registers.append({ "ss", current_regs.ss, current_regs.ss != previous_regs.ss });
m_registers.append({ "ds", current_regs.ds, current_regs.ds != previous_regs.ds });
m_registers.append({ "es", current_regs.es, current_regs.es != previous_regs.es });
m_registers.append({ "fs", current_regs.fs, current_regs.fs != previous_regs.fs });
m_registers.append({ "gs", current_regs.gs, current_regs.gs != previous_regs.gs });
#else
# error Unknown architecture
#endif
}
int RegistersModel::row_count(const GUI::ModelIndex&) const

View file

@ -97,11 +97,13 @@ static int create_thread(pthread_t* thread, void* (*entry)(void*), void* argumen
push_on_stack(thread_params->stack_location);
push_on_stack(argument);
push_on_stack((void*)entry);
#else
#elif ARCH(X86_64)
thread_params->rdi = (FlatPtr)entry;
thread_params->rsi = (FlatPtr)argument;
thread_params->rdx = (FlatPtr)thread_params->stack_location;
thread_params->rcx = thread_params->stack_size;
#else
# error Unknown architecture
#endif
VERIFY((uintptr_t)stack % 16 == 0);

View file

@ -130,17 +130,19 @@ int timingsafe_memcmp(void const* b1, void const* b2, size_t len)
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/memcpy.html
void* memcpy(void* dest_ptr, void const* src_ptr, size_t n)
{
#if ARCH(I386) || ARCH(X86_64)
void* original_dest = dest_ptr;
asm volatile(
"rep movsb"
: "+D"(dest_ptr), "+S"(src_ptr), "+c"(n)::"memory");
return original_dest;
#else
# error Unknown architecture
#endif
}
#if ARCH(I386)
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/memset.html
//
// For x86-64, an optimized ASM implementation is found in ./arch/x86_64/memset.S
void* memset(void* dest_ptr, int c, size_t n)
{
size_t dest = (size_t)dest_ptr;
@ -164,6 +166,10 @@ void* memset(void* dest_ptr, int c, size_t n)
: "memory");
return dest_ptr;
}
#elif ARCH(X86_64)
// For x86-64, an optimized ASM implementation is found in ./arch/x86_64/memset.S
#else
# error Unknown architecture
#endif
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/memmove.html

View file

@ -47,9 +47,11 @@ Backtrace::Backtrace(Reader const& coredump, const ELF::Core::ThreadInfo& thread
#if ARCH(I386)
auto start_bp = m_thread_info.regs.ebp;
auto start_ip = m_thread_info.regs.eip;
#else
#elif ARCH(X86_64)
auto start_bp = m_thread_info.regs.rbp;
auto start_ip = m_thread_info.regs.rip;
#else
# error Unknown architecture
#endif
// In order to provide progress updates, we first have to walk the

View file

@ -169,8 +169,10 @@ NonnullOwnPtrVector<DebugInfo::VariableInfo> DebugInfo::get_variables_in_current
FlatPtr ip;
#if ARCH(I386)
ip = regs.eip;
#else
#elif ARCH(X86_64)
ip = regs.rip;
#else
# error Unknown architecture
#endif
if (ip - m_base_address < scope.address_low || ip - m_base_address >= scope.address_high)
continue;

View file

@ -346,8 +346,10 @@ FlatPtr DebugSession::single_step()
constexpr u32 TRAP_FLAG = 0x100;
#if ARCH(I386)
regs.eflags |= TRAP_FLAG;
#else
#elif ARCH(X86_64)
regs.rflags |= TRAP_FLAG;
#else
# error Unknown architecture
#endif
set_registers(regs);
@ -361,8 +363,10 @@ FlatPtr DebugSession::single_step()
regs = get_registers();
#if ARCH(I386)
regs.eflags &= ~(TRAP_FLAG);
#else
#elif ARCH(X86_64)
regs.rflags &= ~(TRAP_FLAG);
#else
# error Unknown architecture
#endif
set_registers(regs);
return regs.ip();

View file

@ -186,8 +186,10 @@ void DebugSession::run(DesiredInitialDebugeeState initial_debugee_state, Callbac
#if ARCH(I386)
FlatPtr current_instruction = regs.eip;
#else
#elif ARCH(X86_64)
FlatPtr current_instruction = regs.rip;
#else
# error Unknown architecture
#endif
auto debug_status = peek_debug(DEBUG_STATUS_REGISTER);
@ -207,8 +209,10 @@ void DebugSession::run(DesiredInitialDebugeeState initial_debugee_state, Callbac
#if ARCH(I386)
FlatPtr current_ebp = regs.ebp;
#else
#elif ARCH(X86_64)
FlatPtr current_ebp = regs.rbp;
#else
# error Unknown architecture
#endif
do {
@ -253,8 +257,10 @@ void DebugSession::run(DesiredInitialDebugeeState initial_debugee_state, Callbac
auto breakpoint_addr = bit_cast<FlatPtr>(current_breakpoint.value().address);
#if ARCH(I386)
regs.eip = breakpoint_addr;
#else
#elif ARCH(X86_64)
regs.rip = breakpoint_addr;
#else
# error Unknown architecture
#endif
set_registers(regs);
disable_breakpoint(current_breakpoint.value().address);

View file

@ -45,8 +45,10 @@ Optional<FlatPtr> kernel_base()
auto kernel_base_str = String { file.value()->read_all(), NoChomp };
#if ARCH(I386)
using AddressType = u32;
#else
#elif ARCH(X86_64) || ARCH(AARCH64)
using AddressType = u64;
#else
# error Unknown architecture
#endif
auto maybe_kernel_base = kernel_base_str.to_uint<AddressType>();
if (!maybe_kernel_base.has_value()) {

View file

@ -20,8 +20,10 @@ namespace Web {
#if ARCH(I386)
# define CPU_STRING "x86"
#else
#elif ARCH(X86_64)
# define CPU_STRING "x86_64"
#elif ARCH(AARCH64)
# define CPU_STRING "AArch64"
#endif
constexpr auto default_user_agent = "Mozilla/5.0 (SerenityOS; " CPU_STRING ") LibWeb+LibJS/1.0 Browser/1.0";

View file

@ -58,7 +58,7 @@ static void print_syscall(PtraceRegisters& regs, size_t depth)
regs.ecx,
regs.ebx,
end_color);
#else
#elif ARCH(X86_64)
outln("=> {}SC_{}({:#x}, {:#x}, {:#x}){}",
begin_color,
Syscall::to_string((Syscall::Function)regs.rax),
@ -66,6 +66,8 @@ static void print_syscall(PtraceRegisters& regs, size_t depth)
regs.rcx,
regs.rbx,
end_color);
#else
# error Unknown architecture
#endif
}
@ -141,8 +143,10 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
#if ARCH(I386)
const FlatPtr ip = regs.value().eip;
#else
#elif ARCH(X86_64)
const FlatPtr ip = regs.value().rip;
#else
# error Unknown architecture
#endif
if (new_function) {

View file

@ -212,7 +212,7 @@ static int g_pid = -1;
#if ARCH(I386)
using syscall_arg_t = u32;
#else
#elif ARCH(X86_64) || ARCH(AARCH64)
using syscall_arg_t = u64;
#endif
@ -889,11 +889,13 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
syscall_arg_t arg1 = regs.edx;
syscall_arg_t arg2 = regs.ecx;
syscall_arg_t arg3 = regs.ebx;
#else
#elif ARCH(X86_64)
syscall_arg_t syscall_index = regs.rax;
syscall_arg_t arg1 = regs.rdx;
syscall_arg_t arg2 = regs.rcx;
syscall_arg_t arg3 = regs.rbx;
#else
# error Unknown architecture
#endif
TRY(Core::System::ptrace(PT_SYSCALL, g_pid, 0, 0));
@ -906,8 +908,10 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
#if ARCH(I386)
u32 res = regs.eax;
#else
#elif ARCH(X86_64)
u64 res = regs.rax;
#else
# error Unknown architecture
#endif
auto syscall_function = (Syscall::Function)syscall_index;