Compare commits
2 Commits
6affef76b1
...
e8bcebfb8e
Author | SHA1 | Date |
---|---|---|
Bananymous | e8bcebfb8e | |
Bananymous | 2f241e1b61 |
|
@ -189,9 +189,39 @@ namespace Kernel
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> FileBackedRegion::clone(PageTable&)
|
BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> FileBackedRegion::clone(PageTable& page_table)
|
||||||
{
|
{
|
||||||
ASSERT_NOT_REACHED();
|
const size_t aligned_size = (m_size + PAGE_SIZE - 1) & PAGE_ADDR_MASK;
|
||||||
|
auto result = TRY(FileBackedRegion::create(m_inode, page_table, m_offset, m_size, { .start = m_vaddr, .end = m_vaddr + aligned_size }, m_type, m_flags));
|
||||||
|
|
||||||
|
// shared regions can just go through demand paging
|
||||||
|
if (m_type == Type::SHARED)
|
||||||
|
return BAN::UniqPtr<MemoryRegion>(BAN::move(result));
|
||||||
|
|
||||||
|
ASSERT(m_type == Type::PRIVATE);
|
||||||
|
|
||||||
|
for (size_t offset = 0; offset < m_size; offset += PAGE_SIZE)
|
||||||
|
{
|
||||||
|
const vaddr_t vaddr = m_vaddr + offset;
|
||||||
|
if (m_page_table.physical_address_of(vaddr) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ASSERT(&PageTable::current() == &m_page_table);
|
||||||
|
|
||||||
|
const paddr_t paddr = Heap::get().take_free_page();
|
||||||
|
if (paddr == 0)
|
||||||
|
return BAN::Error::from_errno(ENOMEM);
|
||||||
|
|
||||||
|
page_table.map_page_at(paddr, vaddr, m_flags);
|
||||||
|
|
||||||
|
const size_t to_copy = BAN::Math::min<size_t>(PAGE_SIZE, m_size - offset);
|
||||||
|
PageTable::with_fast_page(paddr, [&] {
|
||||||
|
memcpy(PageTable::fast_page_as_ptr(), reinterpret_cast<void*>(vaddr), to_copy);
|
||||||
|
memset(PageTable::fast_page_as_ptr(to_copy), 0, PAGE_SIZE - to_copy);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return BAN::UniqPtr<MemoryRegion>(BAN::move(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -622,98 +622,57 @@ static void load_program_header(const ElfNativeProgramHeader& program_header, in
|
||||||
return result;
|
return result;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
const uintptr_t aligned_vaddr = program_header.p_vaddr & ~(uintptr_t)0xFFF;
|
if ((program_header.p_vaddr & 0xFFF) || (program_header.p_offset & 0xFFF))
|
||||||
|
{
|
||||||
|
const uintptr_t aligned_addr = program_header.p_vaddr & ~(uintptr_t)0xFFF;
|
||||||
|
|
||||||
|
// unaligned addresses, cannot use file mmap
|
||||||
sys_mmap_t mmap_args;
|
sys_mmap_t mmap_args;
|
||||||
mmap_args.addr = reinterpret_cast<void*>(aligned_vaddr);
|
mmap_args.addr = reinterpret_cast<void*>(aligned_addr);
|
||||||
mmap_args.fildes = -1;
|
mmap_args.fildes = -1;
|
||||||
mmap_args.flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED;
|
mmap_args.flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED;
|
||||||
mmap_args.len = (program_header.p_vaddr + program_header.p_memsz) - aligned_vaddr;
|
mmap_args.len = (program_header.p_vaddr + program_header.p_memsz) - aligned_addr;
|
||||||
mmap_args.off = 0;
|
mmap_args.off = 0;
|
||||||
mmap_args.prot = prot | PROT_WRITE;
|
mmap_args.prot = prot | PROT_WRITE;
|
||||||
|
|
||||||
if (auto ret = syscall(SYS_MMAP, &mmap_args); ret != static_cast<long>(aligned_vaddr))
|
if (auto ret = syscall(SYS_MMAP, &mmap_args); ret != static_cast<long>(aligned_addr))
|
||||||
print_error_and_exit("could not load program header", ret);
|
|
||||||
if (auto ret = syscall(SYS_PREAD, fd, program_header.p_vaddr, program_header.p_filesz, program_header.p_offset); ret != static_cast<long>(program_header.p_filesz))
|
|
||||||
print_error_and_exit("could not load program header", ret);
|
print_error_and_exit("could not load program header", ret);
|
||||||
|
|
||||||
return;
|
const uintptr_t addr = program_header.p_vaddr;
|
||||||
|
const uintptr_t size = program_header.p_filesz;
|
||||||
|
const size_t offset = program_header.p_offset;
|
||||||
|
if (auto ret = syscall(SYS_PREAD, fd, addr, size, offset); ret != static_cast<long>(size))
|
||||||
|
print_error_and_exit("could not load program header", ret);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// aligned addresses, use file mmap
|
||||||
|
sys_mmap_t mmap_args;
|
||||||
|
mmap_args.addr = reinterpret_cast<void*>(program_header.p_vaddr);
|
||||||
|
mmap_args.fildes = fd;
|
||||||
|
mmap_args.flags = MAP_PRIVATE | MAP_FIXED;
|
||||||
|
mmap_args.len = program_header.p_memsz;
|
||||||
|
mmap_args.off = program_header.p_offset;
|
||||||
|
mmap_args.prot = prot | PROT_WRITE;
|
||||||
|
|
||||||
uintptr_t filesz = program_header.p_filesz;
|
if (auto ret = syscall(SYS_MMAP, &mmap_args); ret != static_cast<long>(program_header.p_vaddr))
|
||||||
|
print_error_and_exit("could not load program header", ret);
|
||||||
|
}
|
||||||
|
|
||||||
if (program_header.p_filesz != program_header.p_memsz)
|
if (program_header.p_filesz != program_header.p_memsz)
|
||||||
{
|
{
|
||||||
const uintptr_t data_end_vaddr = program_header.p_vaddr + program_header.p_filesz;
|
memset(
|
||||||
const uintptr_t zero_end_vaddr = program_header.p_vaddr + program_header.p_memsz;
|
reinterpret_cast<void*>(program_header.p_vaddr + program_header.p_filesz),
|
||||||
|
0x00,
|
||||||
uintptr_t start_vaddr = data_end_vaddr & ~(uintptr_t)0xFFF;
|
program_header.p_memsz - program_header.p_filesz
|
||||||
if (program_header.p_vaddr & 0xFFF)
|
);
|
||||||
start_vaddr = program_header.p_vaddr & ~(uintptr_t)0xFFF;
|
}
|
||||||
|
|
||||||
if (start_vaddr != data_end_vaddr)
|
|
||||||
{
|
|
||||||
const uintptr_t end_vaddr = (data_end_vaddr + 4095) & ~(uintptr_t)0xFFF;
|
|
||||||
const ptrdiff_t length = min(end_vaddr - start_vaddr, zero_end_vaddr - start_vaddr);
|
|
||||||
|
|
||||||
sys_mmap_t mmap_args;
|
|
||||||
mmap_args.addr = reinterpret_cast<void*>(start_vaddr);
|
|
||||||
mmap_args.fildes = -1;
|
|
||||||
mmap_args.flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED;
|
|
||||||
mmap_args.len = length;
|
|
||||||
mmap_args.off = 0;
|
|
||||||
mmap_args.prot = prot | PROT_WRITE;
|
|
||||||
|
|
||||||
if (auto ret = syscall(SYS_MMAP, &mmap_args); ret != static_cast<long>(start_vaddr))
|
|
||||||
print_error_and_exit("could not load program header", ret);
|
|
||||||
|
|
||||||
uintptr_t dummy_bytes = program_header.p_vaddr - start_vaddr;
|
|
||||||
if (program_header.p_vaddr & 0xFFF)
|
|
||||||
dummy_bytes = 0;
|
|
||||||
|
|
||||||
const uintptr_t data_vaddr = program_header.p_vaddr + dummy_bytes;
|
|
||||||
const ptrdiff_t data_bytes = data_end_vaddr - data_vaddr;
|
|
||||||
const uintptr_t data_offset = program_header.p_offset + dummy_bytes;
|
|
||||||
if (auto ret = syscall(SYS_PREAD, fd, data_vaddr, data_bytes, data_offset); ret != data_bytes)
|
|
||||||
print_error_and_exit("could not load program header", ret);
|
|
||||||
|
|
||||||
if (!(prot & PROT_WRITE) && !needs_writable)
|
if (!(prot & PROT_WRITE) && !needs_writable)
|
||||||
{
|
{
|
||||||
// FIXME: Implement mprotect so PROT_WRITE can be removed
|
// FIXME: Implement mprotect so PROT_WRITE can be removed
|
||||||
//syscall(SYS_MPROTECT, start_vaddr, length, prot);
|
//syscall(SYS_MPROTECT, start_vaddr, length, prot);
|
||||||
}
|
}
|
||||||
|
|
||||||
filesz -= data_bytes;
|
|
||||||
start_vaddr += 4096;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start_vaddr < zero_end_vaddr)
|
|
||||||
{
|
|
||||||
sys_mmap_t mmap_args;
|
|
||||||
mmap_args.addr = reinterpret_cast<void*>(start_vaddr);
|
|
||||||
mmap_args.fildes = -1;
|
|
||||||
mmap_args.flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED;
|
|
||||||
mmap_args.len = zero_end_vaddr - start_vaddr;
|
|
||||||
mmap_args.off = 0;
|
|
||||||
mmap_args.prot = prot | (needs_writable ? PROT_WRITE : 0);
|
|
||||||
|
|
||||||
if (auto ret = syscall(SYS_MMAP, &mmap_args); ret != static_cast<long>(start_vaddr))
|
|
||||||
print_error_and_exit("could not load program header", ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filesz)
|
|
||||||
{
|
|
||||||
sys_mmap_t mmap_args;
|
|
||||||
mmap_args.addr = reinterpret_cast<void*>(program_header.p_vaddr);
|
|
||||||
mmap_args.fildes = fd;
|
|
||||||
mmap_args.flags = MAP_PRIVATE | MAP_FIXED;
|
|
||||||
mmap_args.len = filesz;
|
|
||||||
mmap_args.off = program_header.p_offset;
|
|
||||||
mmap_args.prot = prot | (needs_writable ? PROT_WRITE : 0);
|
|
||||||
|
|
||||||
if (auto ret = syscall(SYS_MMAP, &mmap_args); ret != static_cast<long>(program_header.p_vaddr))
|
|
||||||
print_error_and_exit("could not load program header", ret);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static LoadedElf s_loaded_files[128];
|
static LoadedElf s_loaded_files[128];
|
||||||
|
|
|
@ -56,6 +56,14 @@ void* memcpy(void* __restrict dstp, const void* __restrict srcp, size_t n)
|
||||||
return dstp;
|
return dstp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* memset(void* s, int c, size_t n)
|
||||||
|
{
|
||||||
|
unsigned char* p = static_cast<unsigned char*>(s);
|
||||||
|
for (size_t i = 0; i < n; i++)
|
||||||
|
p[i] = c;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
static int s_random_fd;
|
static int s_random_fd;
|
||||||
|
|
||||||
void init_random()
|
void init_random()
|
||||||
|
|
|
@ -42,7 +42,9 @@ inline void print_uint(int fd, T val, uint8_t base = 10)
|
||||||
|
|
||||||
int strcmp(const char* s1, const char* s2);
|
int strcmp(const char* s1, const char* s2);
|
||||||
char* strcpy(char* __restrict s1, const char* __restrict s2);
|
char* strcpy(char* __restrict s1, const char* __restrict s2);
|
||||||
|
|
||||||
void* memcpy(void* __restrict s1, const void* __restrict s2, size_t n);
|
void* memcpy(void* __restrict s1, const void* __restrict s2, size_t n);
|
||||||
|
void* memset(void* s, int c, size_t n);
|
||||||
|
|
||||||
void init_random();
|
void init_random();
|
||||||
void fini_random();
|
void fini_random();
|
||||||
|
|
Loading…
Reference in New Issue