Compare commits

...

3 Commits

Author SHA1 Message Date
Bananymous 19d16620a6 DynamicLoader: Don't do file backed mapping for filesz == 0 2024-09-05 14:50:05 +03:00
Bananymous 4e15b9cdfa Ports: Add explicit -libgcc-shared for ports on 32 bit 2024-09-05 14:49:23 +03:00
Bananymous de35cec2e1 Kernel: Allow private file mappings past file end
This is just to make memory mapping ELF files easier :D
2024-09-05 14:48:42 +03:00
3 changed files with 42 additions and 20 deletions

View File

@ -13,8 +13,20 @@ namespace Kernel
if (offset < 0 || offset % PAGE_SIZE || size == 0) if (offset < 0 || offset % PAGE_SIZE || size == 0)
return BAN::Error::from_errno(EINVAL); return BAN::Error::from_errno(EINVAL);
if (size > (size_t)inode->size() || (size_t)offset > (size_t)inode->size() - size) switch (type)
return BAN::Error::from_errno(EOVERFLOW); {
case Type::PRIVATE:
if (offset >= inode->size())
return BAN::Error::from_errno(EOVERFLOW);
break;
case Type::SHARED:
if ((size > (size_t)inode->size() || (size_t)offset > (size_t)inode->size() - size))
return BAN::Error::from_errno(EOVERFLOW);
break;
default:
ASSERT_NOT_REACHED();
break;
}
auto* region_ptr = new FileBackedRegion(inode, page_table, offset, size, type, flags); auto* region_ptr = new FileBackedRegion(inode, page_table, offset, size, type, flags);
if (region_ptr == nullptr) if (region_ptr == nullptr)
@ -112,7 +124,7 @@ namespace Kernel
ASSERT(contains(address)); ASSERT(contains(address));
// Check if address is already mapped // Check if address is already mapped
vaddr_t vaddr = address & PAGE_ADDR_MASK; const vaddr_t vaddr = address & PAGE_ADDR_MASK;
if (m_page_table.physical_address_of(vaddr) != 0) if (m_page_table.physical_address_of(vaddr) != 0)
return false; return false;
@ -126,25 +138,30 @@ namespace Kernel
// Temporarily force mapping to be writable so kernel can write to it // Temporarily force mapping to be writable so kernel can write to it
m_page_table.map_page_at(paddr, vaddr, m_flags | PageTable::Flags::ReadWrite); m_page_table.map_page_at(paddr, vaddr, m_flags | PageTable::Flags::ReadWrite);
size_t file_offset = m_offset + (vaddr - m_vaddr);
size_t bytes = BAN::Math::min<size_t>(m_size - file_offset, PAGE_SIZE);
ASSERT(&PageTable::current() == &m_page_table); ASSERT(&PageTable::current() == &m_page_table);
auto read_ret = m_inode->read(file_offset, BAN::ByteSpan((uint8_t*)vaddr, bytes)); memset(reinterpret_cast<void*>(vaddr), 0x00, PAGE_SIZE);
if (read_ret.is_error()) const size_t file_offset = m_offset + (vaddr - m_vaddr);
{
Heap::get().release_page(paddr);
m_page_table.unmap_page(vaddr);
return read_ret.release_error();
}
if (read_ret.value() < bytes) if (file_offset < static_cast<size_t>(m_inode->size()))
{ {
dwarnln("Only {}/{} bytes read", read_ret.value(), bytes); const size_t bytes = BAN::Math::min<size_t>(BAN::Math::min<size_t>(m_offset + m_size, m_inode->size()) - file_offset, PAGE_SIZE);
Heap::get().release_page(paddr); auto read_ret = m_inode->read(file_offset, BAN::ByteSpan((uint8_t*)vaddr, bytes));
m_page_table.unmap_page(vaddr);
return BAN::Error::from_errno(EIO); if (read_ret.is_error())
{
Heap::get().release_page(paddr);
m_page_table.unmap_page(vaddr);
return read_ret.release_error();
}
if (read_ret.value() < bytes)
{
dwarnln("Only {}/{} bytes read", read_ret.value(), bytes);
Heap::get().release_page(paddr);
m_page_table.unmap_page(vaddr);
return BAN::Error::from_errno(EIO);
}
} }
// Disable writable if not wanted // Disable writable if not wanted
@ -172,7 +189,8 @@ namespace Kernel
TRY(m_inode->read(offset, BAN::ByteSpan(m_shared_data->page_buffer, bytes))); TRY(m_inode->read(offset, BAN::ByteSpan(m_shared_data->page_buffer, bytes)));
PageTable::with_fast_page(pages[page_index], [&] { PageTable::with_fast_page(pages[page_index], [&] {
memcpy(PageTable::fast_page_as_ptr(), m_shared_data->page_buffer, PAGE_SIZE); memcpy(PageTable::fast_page_as_ptr(), m_shared_data->page_buffer, bytes);
memset(PageTable::fast_page_as_ptr(bytes), 0x00, PAGE_SIZE - bytes);
}); });
} }

View File

@ -36,6 +36,10 @@ if [ ! -f "$BANAN_SYSROOT/usr/lib/libc.a" ]; then
popd >/dev/null popd >/dev/null
fi fi
if [ "$BANAN_ARCH" = "i686" ]; then
export LDFLAGS="-shared-libgcc"
fi
clean() { clean() {
find . -mindepth 1 -maxdepth 1 -not -name 'patches' -not -name 'build.sh' -exec rm -rf {} + find . -mindepth 1 -maxdepth 1 -not -name 'patches' -not -name 'build.sh' -exec rm -rf {} +
} }

View File

@ -622,7 +622,7 @@ static void load_program_header(const ElfNativeProgramHeader& program_header, in
return result; return result;
}(); }();
if ((program_header.p_vaddr & 0xFFF) || (program_header.p_offset & 0xFFF)) if ((program_header.p_vaddr & 0xFFF) || (program_header.p_offset & 0xFFF) || program_header.p_filesz == 0)
{ {
const uintptr_t aligned_addr = program_header.p_vaddr & ~(uintptr_t)0xFFF; const uintptr_t aligned_addr = program_header.p_vaddr & ~(uintptr_t)0xFFF;