mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-02 16:53:17 +00:00
core: Many things (#194)
* video_core: Add a few missed things * libkernel: More proper memory mapped files * memory: Fix tessellation buffer mapping * Cuphead work * sceKernelPollSema fix * clang format * fixed ngs2 lle loading and rtc lib * draft pthreads keys implementation * fixed return codes * return error code if sceKernelLoadStartModule module is invalid * re-enabled system modules and disable debug in libs.h * Improve linux support * fix windows build * kernel: Rework keys --------- Co-authored-by: georgemoralis <giorgosmrls@gmail.com>
This commit is contained in:
parent
6a47f8ae50
commit
c5d1d579b1
67 changed files with 1406 additions and 307 deletions
137
src/core/loader/dwarf.cpp
Normal file
137
src/core/loader/dwarf.cpp
Normal file
|
@ -0,0 +1,137 @@
|
|||
// SPDX-FileCopyrightText: Copyright (C) 2001-2024 Free Software Foundation, Inc.
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/loader/dwarf.h"
|
||||
|
||||
namespace Dwarf {
|
||||
|
||||
template <typename T>
|
||||
T get(uintptr_t addr) {
|
||||
T val;
|
||||
memcpy(&val, reinterpret_cast<void*>(addr), sizeof(T));
|
||||
return val;
|
||||
}
|
||||
|
||||
static uintptr_t getEncodedP(uintptr_t& addr, uintptr_t end, u8 encoding, uintptr_t datarelBase) {
|
||||
const uintptr_t startAddr = addr;
|
||||
const u8* p = (u8*)addr;
|
||||
uintptr_t result;
|
||||
|
||||
// First get value
|
||||
switch (encoding & 0x0F) {
|
||||
case DW_EH_PE_ptr:
|
||||
result = get<uintptr_t>(addr);
|
||||
p += sizeof(uintptr_t);
|
||||
addr = (uintptr_t)p;
|
||||
break;
|
||||
case DW_EH_PE_udata2:
|
||||
result = get<u16>(addr);
|
||||
p += sizeof(u16);
|
||||
addr = (uintptr_t)p;
|
||||
break;
|
||||
case DW_EH_PE_udata4:
|
||||
result = get<u32>(addr);
|
||||
p += sizeof(u32);
|
||||
addr = (uintptr_t)p;
|
||||
break;
|
||||
case DW_EH_PE_udata8:
|
||||
result = get<u64>(addr);
|
||||
p += sizeof(u64);
|
||||
addr = (uintptr_t)p;
|
||||
break;
|
||||
case DW_EH_PE_sdata2:
|
||||
// Sign extend from signed 16-bit value.
|
||||
result = get<s16>(addr);
|
||||
p += sizeof(s16);
|
||||
addr = (uintptr_t)p;
|
||||
break;
|
||||
case DW_EH_PE_sdata4:
|
||||
// Sign extend from signed 32-bit value.
|
||||
result = get<s32>(addr);
|
||||
p += sizeof(s32);
|
||||
addr = (uintptr_t)p;
|
||||
break;
|
||||
case DW_EH_PE_sdata8:
|
||||
result = get<s64>(addr);
|
||||
p += sizeof(s64);
|
||||
addr = (uintptr_t)p;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE_MSG("unknown pointer encoding");
|
||||
}
|
||||
|
||||
// Then add relative offset
|
||||
switch (encoding & 0x70) {
|
||||
case DW_EH_PE_absptr:
|
||||
// do nothing
|
||||
break;
|
||||
case DW_EH_PE_pcrel:
|
||||
result += startAddr;
|
||||
break;
|
||||
case DW_EH_PE_textrel:
|
||||
UNREACHABLE_MSG("DW_EH_PE_textrel pointer encoding not supported");
|
||||
break;
|
||||
case DW_EH_PE_datarel:
|
||||
// DW_EH_PE_datarel is only valid in a few places, so the parameter has a
|
||||
// default value of 0, and we abort in the event that someone calls this
|
||||
// function with a datarelBase of 0 and DW_EH_PE_datarel encoding.
|
||||
if (datarelBase == 0)
|
||||
UNREACHABLE_MSG("DW_EH_PE_datarel is invalid with a datarelBase of 0");
|
||||
result += datarelBase;
|
||||
break;
|
||||
case DW_EH_PE_funcrel:
|
||||
UNREACHABLE_MSG("DW_EH_PE_funcrel pointer encoding not supported");
|
||||
break;
|
||||
case DW_EH_PE_aligned:
|
||||
UNREACHABLE_MSG("DW_EH_PE_aligned pointer encoding not supported");
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE_MSG("unknown pointer encoding");
|
||||
break;
|
||||
}
|
||||
|
||||
if (encoding & DW_EH_PE_indirect) {
|
||||
result = get<uintptr_t>(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DecodeEHHdr(uintptr_t ehHdrStart, uintptr_t ehHdrEnd, EHHeaderInfo& ehHdrInfo) {
|
||||
auto p = ehHdrStart;
|
||||
// Ensure that we don't read data beyond the end of .eh_frame_hdr
|
||||
if (ehHdrEnd - ehHdrStart < 4) {
|
||||
// Don't print a message for an empty .eh_frame_hdr (this can happen if
|
||||
// the linker script defines symbols for it even in the empty case).
|
||||
if (ehHdrEnd == ehHdrStart) {
|
||||
return false;
|
||||
}
|
||||
LOG_ERROR(Core_Linker,
|
||||
"Unsupported .eh_frame_hdr at {:#x} "
|
||||
"need at least 4 bytes of data but only got {:#x}",
|
||||
ehHdrStart, ehHdrEnd - ehHdrStart);
|
||||
return false;
|
||||
}
|
||||
|
||||
const u8 version = get<u8>(p++);
|
||||
if (version != 1) {
|
||||
LOG_CRITICAL(Core_Linker, "Unsupported .eh_frame_hdr version: {:#x} at {:#x}", version,
|
||||
ehHdrStart);
|
||||
return false;
|
||||
}
|
||||
|
||||
const u8 eh_frame_ptr_enc = get<u8>(p++);
|
||||
const u8 fde_count_enc = get<u8>(p++);
|
||||
ehHdrInfo.table_enc = get<u8>(p++);
|
||||
|
||||
ehHdrInfo.eh_frame_ptr = getEncodedP(p, ehHdrEnd, eh_frame_ptr_enc, ehHdrStart);
|
||||
ehHdrInfo.fde_count =
|
||||
fde_count_enc == DW_EH_PE_omit ? 0 : getEncodedP(p, ehHdrEnd, fde_count_enc, ehHdrStart);
|
||||
ehHdrInfo.table = p;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Dwarf
|
41
src/core/loader/dwarf.h
Normal file
41
src/core/loader/dwarf.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
// SPDX-FileCopyrightText: Copyright (C) 2001-2024 Free Software Foundation, Inc.
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.h"
|
||||
|
||||
namespace Dwarf {
|
||||
|
||||
enum {
|
||||
DW_EH_PE_ptr = 0x00,
|
||||
DW_EH_PE_uleb128 = 0x01,
|
||||
DW_EH_PE_udata2 = 0x02,
|
||||
DW_EH_PE_udata4 = 0x03,
|
||||
DW_EH_PE_udata8 = 0x04,
|
||||
DW_EH_PE_signed = 0x08,
|
||||
DW_EH_PE_sleb128 = 0x09,
|
||||
DW_EH_PE_sdata2 = 0x0A,
|
||||
DW_EH_PE_sdata4 = 0x0B,
|
||||
DW_EH_PE_sdata8 = 0x0C,
|
||||
DW_EH_PE_absptr = 0x00,
|
||||
DW_EH_PE_pcrel = 0x10,
|
||||
DW_EH_PE_textrel = 0x20,
|
||||
DW_EH_PE_datarel = 0x30,
|
||||
DW_EH_PE_funcrel = 0x40,
|
||||
DW_EH_PE_aligned = 0x50,
|
||||
DW_EH_PE_indirect = 0x80,
|
||||
DW_EH_PE_omit = 0xFF
|
||||
};
|
||||
|
||||
/// Information encoded in the EH frame header.
|
||||
struct EHHeaderInfo {
|
||||
uintptr_t eh_frame_ptr;
|
||||
size_t fde_count;
|
||||
uintptr_t table;
|
||||
u8 table_enc;
|
||||
};
|
||||
|
||||
bool DecodeEHHdr(uintptr_t ehHdrStart, uintptr_t ehHdrEnd, EHHeaderInfo& ehHdrInfo);
|
||||
|
||||
} // namespace Dwarf
|
|
@ -449,6 +449,15 @@ constexpr u32 R_X86_64_JUMP_SLOT = 7; // Create PLT entry
|
|||
constexpr u32 R_X86_64_RELATIVE = 8; // Adjust by program base
|
||||
constexpr u32 R_X86_64_DTPMOD64 = 16;
|
||||
|
||||
struct eh_frame_hdr {
|
||||
uint8_t version;
|
||||
uint8_t eh_frame_ptr_enc;
|
||||
uint8_t fde_count_enc;
|
||||
uint8_t table_enc;
|
||||
uint32_t eh_frame_ptr;
|
||||
uint32_t fde_count;
|
||||
};
|
||||
|
||||
namespace Core::Loader {
|
||||
|
||||
class Elf {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue