Compare commits
23 Commits
a4698f0bde
...
f15f88ebd6
Author | SHA1 | Date |
---|---|---|
|
f15f88ebd6 | |
|
391fc0c4c2 | |
|
948ef2c820 | |
|
c1b6b6b76a | |
|
a8bb07052e | |
|
6976a2dae7 | |
|
51cd951b4c | |
|
16a5a234c1 | |
|
f994210927 | |
|
aaa8760d09 | |
|
cea19ecc31 | |
|
706cfeb443 | |
|
d9c91589f0 | |
|
9854691265 | |
|
32afa33a06 | |
|
c6946d0145 | |
|
abbe7b79d6 | |
|
e4abe75043 | |
|
b904503691 | |
|
2db42dfb2e | |
|
10bd24e585 | |
|
f926e599fa | |
|
e7b518ba67 |
|
@ -26,18 +26,40 @@ namespace Kernel
|
|||
class BlockBufferWrapper
|
||||
{
|
||||
BAN_NON_COPYABLE(BlockBufferWrapper);
|
||||
BAN_NON_MOVABLE(BlockBufferWrapper);
|
||||
|
||||
public:
|
||||
BlockBufferWrapper(BAN::Span<uint8_t> buffer, bool& used)
|
||||
BlockBufferWrapper(BAN::Span<uint8_t> buffer, bool* used, Mutex* mutex, ThreadBlocker* blocker)
|
||||
: m_buffer(buffer)
|
||||
, m_used(used)
|
||||
, m_mutex(mutex)
|
||||
, m_blocker(blocker)
|
||||
{
|
||||
ASSERT(m_used);
|
||||
ASSERT(m_used && *m_used);
|
||||
}
|
||||
BlockBufferWrapper(BlockBufferWrapper&& other) { *this = BAN::move(other); }
|
||||
~BlockBufferWrapper()
|
||||
{
|
||||
m_used = false;
|
||||
if (m_used == nullptr)
|
||||
return;
|
||||
m_mutex->lock();
|
||||
*m_used = false;
|
||||
m_blocker->unblock();
|
||||
m_mutex->unlock();
|
||||
}
|
||||
|
||||
BlockBufferWrapper& operator=(BlockBufferWrapper&& other)
|
||||
{
|
||||
this->m_buffer = other.m_buffer;
|
||||
this->m_used = other.m_used;
|
||||
this->m_mutex = other.m_mutex;
|
||||
this->m_blocker = other.m_blocker;
|
||||
|
||||
other.m_buffer = {};
|
||||
other.m_used = nullptr;
|
||||
other.m_mutex = nullptr;
|
||||
other.m_blocker = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t size() const { return m_buffer.size(); }
|
||||
|
@ -53,7 +75,9 @@ namespace Kernel
|
|||
|
||||
private:
|
||||
BAN::Span<uint8_t> m_buffer;
|
||||
bool& m_used;
|
||||
bool* m_used;
|
||||
Mutex* m_mutex;
|
||||
ThreadBlocker* m_blocker;
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -79,7 +103,7 @@ namespace Kernel
|
|||
BAN::ErrorOr<void> sync_superblock();
|
||||
BAN::ErrorOr<void> sync_block(uint32_t block);
|
||||
|
||||
BlockBufferWrapper get_block_buffer();
|
||||
BAN::ErrorOr<BlockBufferWrapper> get_block_buffer();
|
||||
|
||||
BAN::ErrorOr<uint32_t> reserve_free_block(uint32_t primary_bgd);
|
||||
BAN::ErrorOr<void> release_block(uint32_t block);
|
||||
|
@ -102,7 +126,7 @@ namespace Kernel
|
|||
{
|
||||
public:
|
||||
BlockBufferManager() = default;
|
||||
BlockBufferWrapper get_buffer();
|
||||
BAN::ErrorOr<BlockBufferWrapper> get_buffer();
|
||||
|
||||
BAN::ErrorOr<void> initialize(size_t block_size);
|
||||
|
||||
|
@ -114,7 +138,9 @@ namespace Kernel
|
|||
};
|
||||
|
||||
private:
|
||||
BAN::Array<BlockBuffer, 10> m_buffers;
|
||||
Mutex m_buffer_mutex;
|
||||
ThreadBlocker m_buffer_blocker;
|
||||
BAN::Array<BlockBuffer, 16> m_buffers;
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
@ -82,4 +82,30 @@ namespace Kernel
|
|||
size_t (*m_callback)(off_t, BAN::ByteSpan);
|
||||
};
|
||||
|
||||
class ProcSymlinkInode final : public TmpInode
|
||||
{
|
||||
public:
|
||||
static BAN::ErrorOr<BAN::RefPtr<ProcSymlinkInode>> create_new(BAN::ErrorOr<BAN::String> (*)(void*), void* data, TmpFileSystem&, mode_t, uid_t, gid_t);
|
||||
~ProcSymlinkInode() = default;
|
||||
|
||||
protected:
|
||||
virtual BAN::ErrorOr<BAN::String> link_target_impl() override;
|
||||
|
||||
// You may not write here and this is always non blocking
|
||||
virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override { return BAN::Error::from_errno(EINVAL); }
|
||||
virtual BAN::ErrorOr<void> truncate_impl(size_t) override { return BAN::Error::from_errno(EINVAL); }
|
||||
|
||||
virtual bool can_read_impl() const override { return false; }
|
||||
virtual bool can_write_impl() const override { return false; }
|
||||
virtual bool has_error_impl() const override { return false; }
|
||||
virtual bool has_hungup_impl() const override { return false; }
|
||||
|
||||
private:
|
||||
ProcSymlinkInode(BAN::ErrorOr<BAN::String> (*callback)(void*), void* data, TmpFileSystem&, const TmpInodeInfo&);
|
||||
|
||||
private:
|
||||
BAN::ErrorOr<BAN::String> (*m_callback)(void*);
|
||||
void* m_data;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -156,6 +156,7 @@ namespace Kernel
|
|||
virtual BAN::ErrorOr<size_t> list_next_inodes_impl(off_t, struct dirent*, size_t) override final;
|
||||
virtual BAN::ErrorOr<void> create_file_impl(BAN::StringView, mode_t, uid_t, gid_t) override final;
|
||||
virtual BAN::ErrorOr<void> create_directory_impl(BAN::StringView, mode_t, uid_t, gid_t) override final;
|
||||
virtual BAN::ErrorOr<void> link_inode_impl(BAN::StringView, BAN::RefPtr<Inode>) override final;
|
||||
virtual BAN::ErrorOr<void> unlink_impl(BAN::StringView) override;
|
||||
|
||||
virtual bool can_read_impl() const override { return false; }
|
||||
|
|
|
@ -226,6 +226,8 @@ namespace Kernel
|
|||
size_t proc_cmdline(off_t offset, BAN::ByteSpan) const;
|
||||
size_t proc_environ(off_t offset, BAN::ByteSpan) const;
|
||||
|
||||
BAN::StringView executable() const { return m_executable; }
|
||||
|
||||
// Returns error if page could not be allocated
|
||||
// Returns true if the page was allocated successfully
|
||||
// Return false if access was page violation (segfault)
|
||||
|
@ -339,6 +341,7 @@ namespace Kernel
|
|||
|
||||
BAN::Vector<BAN::String> m_cmdline;
|
||||
BAN::Vector<BAN::String> m_environ;
|
||||
BAN::String m_executable;
|
||||
|
||||
BAN::Vector<ChildExitStatus> m_child_exit_statuses;
|
||||
ThreadBlocker m_child_exit_blocker;
|
||||
|
|
|
@ -120,6 +120,8 @@ namespace Kernel
|
|||
|
||||
static ProcessorID read_processor_id();
|
||||
|
||||
static void initialize_smp();
|
||||
|
||||
template<typename T>
|
||||
static T read_gs_sized(uintptr_t offset) requires(sizeof(T) <= 8)
|
||||
{
|
||||
|
@ -158,7 +160,7 @@ namespace Kernel
|
|||
static BAN::Atomic<bool> s_is_smp_enabled;
|
||||
static BAN::Atomic<bool> s_should_print_cpu_load;
|
||||
|
||||
ProcessorID m_id { PROCESSOR_NONE };
|
||||
ProcessorID m_id { 0 };
|
||||
|
||||
static constexpr size_t s_stack_size { 4096 };
|
||||
void* m_stack { nullptr };
|
||||
|
@ -173,12 +175,8 @@ namespace Kernel
|
|||
uint64_t m_last_update_ns { 0 };
|
||||
uint64_t m_next_update_ns { 0 };
|
||||
|
||||
BAN::Atomic<bool> m_smp_pending_lock { false };
|
||||
SMPMessage* m_smp_pending { nullptr };
|
||||
|
||||
BAN::Atomic<bool> m_smp_free_lock { false };
|
||||
SMPMessage* m_smp_free { nullptr };
|
||||
|
||||
BAN::Atomic<SMPMessage*> m_smp_pending { nullptr };
|
||||
BAN::Atomic<SMPMessage*> m_smp_free { nullptr };
|
||||
SMPMessage* m_smp_message_storage { nullptr };
|
||||
|
||||
void* m_current_page_table { nullptr };
|
||||
|
|
|
@ -125,7 +125,7 @@ namespace Kernel
|
|||
TRY(m_buffer_manager.initialize(block_size()));
|
||||
|
||||
{
|
||||
auto block_buffer = m_buffer_manager.get_buffer();
|
||||
auto block_buffer = TRY(m_buffer_manager.get_buffer());
|
||||
|
||||
if (superblock().rev_level == Ext2::Enum::GOOD_OLD_REV)
|
||||
{
|
||||
|
@ -170,6 +170,9 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<uint32_t> Ext2FS::create_inode(const Ext2::Inode& ext2_inode)
|
||||
{
|
||||
auto bgd_buffer = TRY(m_buffer_manager.get_buffer());
|
||||
auto inode_bitmap = TRY(m_buffer_manager.get_buffer());
|
||||
|
||||
LockGuard _(m_mutex);
|
||||
|
||||
ASSERT(ext2_inode.size == 0);
|
||||
|
@ -179,9 +182,6 @@ namespace Kernel
|
|||
|
||||
const uint32_t block_size = this->block_size();
|
||||
|
||||
auto bgd_buffer = m_buffer_manager.get_buffer();
|
||||
auto inode_bitmap = m_buffer_manager.get_buffer();
|
||||
|
||||
uint32_t current_group = -1;
|
||||
BlockLocation bgd_location {};
|
||||
Ext2::BlockGroupDescriptor* bgd = nullptr;
|
||||
|
@ -248,15 +248,15 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<void> Ext2FS::delete_inode(uint32_t ino)
|
||||
{
|
||||
auto bgd_buffer = TRY(get_block_buffer());
|
||||
auto bitmap_buffer = TRY(get_block_buffer());
|
||||
auto inode_buffer = TRY(get_block_buffer());
|
||||
|
||||
LockGuard _(m_mutex);
|
||||
|
||||
ASSERT(ino >= superblock().first_ino);
|
||||
ASSERT(ino <= superblock().inodes_count);
|
||||
|
||||
auto bgd_buffer = get_block_buffer();
|
||||
auto bitmap_buffer = get_block_buffer();
|
||||
auto inode_buffer = get_block_buffer();
|
||||
|
||||
const uint32_t inode_group = (ino - 1) / superblock().inodes_per_group;
|
||||
const uint32_t inode_index = (ino - 1) % superblock().inodes_per_group;
|
||||
|
||||
|
@ -334,6 +334,8 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<void> Ext2FS::sync_superblock()
|
||||
{
|
||||
auto superblock_buffer = TRY(get_block_buffer());
|
||||
|
||||
LockGuard _(m_mutex);
|
||||
|
||||
const uint32_t sector_size = m_block_device->blksize();
|
||||
|
@ -347,8 +349,6 @@ namespace Kernel
|
|||
const uint32_t lba = 1024 / sector_size;
|
||||
const uint32_t sector_count = BAN::Math::div_round_up<uint32_t>(superblock_bytes, sector_size);
|
||||
|
||||
auto superblock_buffer = get_block_buffer();
|
||||
|
||||
TRY(m_block_device->read_blocks(lba, sector_count, superblock_buffer.span()));
|
||||
if (memcmp(superblock_buffer.data(), &m_superblock, superblock_bytes))
|
||||
{
|
||||
|
@ -370,22 +370,21 @@ namespace Kernel
|
|||
return m_block_device->sync_blocks(block * sectors_per_block, sectors_per_block);
|
||||
}
|
||||
|
||||
Ext2FS::BlockBufferWrapper Ext2FS::get_block_buffer()
|
||||
BAN::ErrorOr<Ext2FS::BlockBufferWrapper> Ext2FS::get_block_buffer()
|
||||
{
|
||||
LockGuard _(m_mutex);
|
||||
return m_buffer_manager.get_buffer();
|
||||
}
|
||||
|
||||
BAN::ErrorOr<uint32_t> Ext2FS::reserve_free_block(uint32_t primary_bgd)
|
||||
{
|
||||
auto bgd_buffer = TRY(m_buffer_manager.get_buffer());
|
||||
auto block_bitmap = TRY(m_buffer_manager.get_buffer());
|
||||
|
||||
LockGuard _(m_mutex);
|
||||
|
||||
if (m_superblock.r_blocks_count >= m_superblock.free_blocks_count)
|
||||
return BAN::Error::from_errno(ENOSPC);
|
||||
|
||||
auto bgd_buffer = m_buffer_manager.get_buffer();
|
||||
auto block_bitmap = m_buffer_manager.get_buffer();
|
||||
|
||||
auto check_block_group =
|
||||
[&](uint32_t block_group) -> BAN::ErrorOr<uint32_t>
|
||||
{
|
||||
|
@ -439,6 +438,9 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<void> Ext2FS::release_block(uint32_t block)
|
||||
{
|
||||
auto bgd_buffer = TRY(get_block_buffer());
|
||||
auto bitmap_buffer = TRY(get_block_buffer());
|
||||
|
||||
LockGuard _(m_mutex);
|
||||
|
||||
ASSERT(block >= m_superblock.first_data_block);
|
||||
|
@ -447,9 +449,6 @@ namespace Kernel
|
|||
const uint32_t block_group = (block - m_superblock.first_data_block) / m_superblock.blocks_per_group;
|
||||
const uint32_t block_offset = (block - m_superblock.first_data_block) % m_superblock.blocks_per_group;
|
||||
|
||||
auto bgd_buffer = get_block_buffer();
|
||||
auto bitmap_buffer = get_block_buffer();
|
||||
|
||||
auto bgd_location = locate_block_group_descriptior(block_group);
|
||||
TRY(read_block(bgd_location.block, bgd_buffer));
|
||||
|
||||
|
@ -480,7 +479,7 @@ namespace Kernel
|
|||
|
||||
const uint32_t block_size = this->block_size();
|
||||
|
||||
auto bgd_buffer = m_buffer_manager.get_buffer();
|
||||
auto bgd_buffer = TRY(m_buffer_manager.get_buffer());
|
||||
|
||||
const uint32_t inode_group = (ino - 1) / superblock().inodes_per_group;
|
||||
const uint32_t inode_index = (ino - 1) % superblock().inodes_per_group;
|
||||
|
@ -533,16 +532,22 @@ namespace Kernel
|
|||
};
|
||||
}
|
||||
|
||||
Ext2FS::BlockBufferWrapper Ext2FS::BlockBufferManager::get_buffer()
|
||||
BAN::ErrorOr<Ext2FS::BlockBufferWrapper> Ext2FS::BlockBufferManager::get_buffer()
|
||||
{
|
||||
for (auto& buffer : m_buffers)
|
||||
LockGuard _(m_buffer_mutex);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (buffer.used)
|
||||
continue;
|
||||
buffer.used = true;
|
||||
return Ext2FS::BlockBufferWrapper(buffer.buffer.span(), buffer.used);
|
||||
for (auto& buffer : m_buffers)
|
||||
{
|
||||
if (buffer.used)
|
||||
continue;
|
||||
buffer.used = true;
|
||||
return Ext2FS::BlockBufferWrapper(buffer.buffer.span(), &buffer.used, &m_buffer_mutex, &m_buffer_blocker);
|
||||
}
|
||||
|
||||
TRY(Thread::current().block_or_eintr_indefinite(m_buffer_blocker, &m_buffer_mutex));
|
||||
}
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Ext2FS::BlockBufferManager::initialize(size_t block_size)
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace Kernel
|
|||
|
||||
auto inode_location = TRY(fs.locate_inode(inode_ino));
|
||||
|
||||
auto block_buffer = fs.get_block_buffer();
|
||||
auto block_buffer = TRY(fs.get_block_buffer());
|
||||
TRY(fs.read_block(inode_location.block, block_buffer));
|
||||
|
||||
auto& inode = block_buffer.span().slice(inode_location.offset).as<Ext2::Inode>();
|
||||
|
@ -61,7 +61,7 @@ namespace Kernel
|
|||
return BAN::Optional<uint32_t>();
|
||||
ASSERT(depth >= 1);
|
||||
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
auto block_buffer = TRY(m_fs.get_block_buffer());
|
||||
TRY(m_fs.read_block(block, block_buffer));
|
||||
|
||||
const uint32_t indices_per_block = blksize() / sizeof(uint32_t);
|
||||
|
@ -152,7 +152,7 @@ namespace Kernel
|
|||
|
||||
const uint32_t block_size = blksize();
|
||||
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
auto block_buffer = TRY(m_fs.get_block_buffer());
|
||||
|
||||
const uint32_t first_block = offset / block_size;
|
||||
const uint32_t last_block = BAN::Math::div_round_up<uint32_t>(offset + count, block_size);
|
||||
|
@ -192,7 +192,7 @@ namespace Kernel
|
|||
|
||||
const uint32_t block_size = blksize();
|
||||
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
auto block_buffer = TRY(m_fs.get_block_buffer());
|
||||
|
||||
size_t written = 0;
|
||||
size_t to_write = buffer.size();
|
||||
|
@ -349,7 +349,7 @@ namespace Kernel
|
|||
return {};
|
||||
}
|
||||
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
auto block_buffer = TRY(m_fs.get_block_buffer());
|
||||
TRY(m_fs.read_block(block, block_buffer));
|
||||
|
||||
const uint32_t ids_per_block = blksize() / sizeof(uint32_t);
|
||||
|
@ -409,7 +409,7 @@ done:
|
|||
// FIXME: can we actually assume directories have all their blocks allocated
|
||||
const uint32_t block_index = TRY(fs_block_of_data_block_index(offset)).value();
|
||||
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
auto block_buffer = TRY(m_fs.get_block_buffer());
|
||||
|
||||
TRY(m_fs.read_block(block_index, block_buffer));
|
||||
|
||||
|
@ -569,9 +569,7 @@ done:
|
|||
{
|
||||
ASSERT(this->mode().ifdir());
|
||||
ASSERT(!inode->mode().ifdir());
|
||||
|
||||
if (&m_fs != inode->filesystem())
|
||||
return BAN::Error::from_errno(EXDEV);
|
||||
ASSERT(&m_fs == inode->filesystem());
|
||||
|
||||
if (!find_inode_impl(name).is_error())
|
||||
return BAN::Error::from_errno(EEXIST);
|
||||
|
@ -604,7 +602,7 @@ done:
|
|||
|
||||
const uint32_t block_size = m_fs.block_size();
|
||||
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
auto block_buffer = TRY(m_fs.get_block_buffer());
|
||||
|
||||
auto write_inode =
|
||||
[&](uint32_t entry_offset, uint32_t entry_rec_len) -> BAN::ErrorOr<void>
|
||||
|
@ -691,7 +689,7 @@ needs_new_block:
|
|||
{
|
||||
ASSERT(mode().ifdir());
|
||||
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
auto block_buffer = TRY(m_fs.get_block_buffer());
|
||||
|
||||
// Confirm that this doesn't contain anything else than '.' or '..'
|
||||
for (uint32_t i = 0; i < max_used_data_block_count(); i++)
|
||||
|
@ -728,7 +726,7 @@ needs_new_block:
|
|||
return BAN::Error::from_errno(ENOTSUP);
|
||||
}
|
||||
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
auto block_buffer = TRY(m_fs.get_block_buffer());
|
||||
|
||||
for (uint32_t i = 0; i < max_used_data_block_count(); i++)
|
||||
{
|
||||
|
@ -784,7 +782,7 @@ needs_new_block:
|
|||
return BAN::Error::from_errno(ENOTSUP);
|
||||
}
|
||||
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
auto block_buffer = TRY(m_fs.get_block_buffer());
|
||||
|
||||
for (uint32_t i = 0; i < max_used_data_block_count(); i++)
|
||||
{
|
||||
|
@ -846,7 +844,7 @@ needs_new_block:
|
|||
block = TRY(m_fs.reserve_free_block(block_group()));
|
||||
m_inode.blocks += inode_blocks_per_fs_block;
|
||||
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
auto block_buffer = TRY(m_fs.get_block_buffer());
|
||||
memset(block_buffer.data(), 0x00, block_buffer.size());
|
||||
TRY(m_fs.write_block(block, block_buffer));
|
||||
}
|
||||
|
@ -854,7 +852,7 @@ needs_new_block:
|
|||
if (depth == 0)
|
||||
return block;
|
||||
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
auto block_buffer = TRY(m_fs.get_block_buffer());
|
||||
TRY(m_fs.read_block(block, block_buffer));
|
||||
|
||||
uint32_t divisor = 1;
|
||||
|
@ -903,7 +901,7 @@ needs_new_block:
|
|||
BAN::ErrorOr<void> Ext2Inode::sync()
|
||||
{
|
||||
auto inode_location = TRY(m_fs.locate_inode(ino()));
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
auto block_buffer = TRY(m_fs.get_block_buffer());
|
||||
|
||||
TRY(m_fs.read_block(inode_location.block, block_buffer));
|
||||
if (memcmp(block_buffer.data() + inode_location.offset, &m_inode, sizeof(Ext2::Inode)))
|
||||
|
@ -919,7 +917,7 @@ needs_new_block:
|
|||
{
|
||||
ASSERT(mode().ifdir());
|
||||
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
auto block_buffer = TRY(m_fs.get_block_buffer());
|
||||
|
||||
for (uint32_t i = 0; i < max_used_data_block_count(); i++)
|
||||
{
|
||||
|
|
|
@ -107,6 +107,8 @@ namespace Kernel
|
|||
return BAN::Error::from_errno(ENOTDIR);
|
||||
if (inode->mode().ifdir())
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
if (this->filesystem() != inode->filesystem())
|
||||
return BAN::Error::from_errno(EXDEV);
|
||||
if (auto* fs = filesystem(); fs && (fs->flag() & ST_RDONLY))
|
||||
return BAN::Error::from_errno(EROFS);
|
||||
return link_inode_impl(name, inode);
|
||||
|
|
|
@ -38,6 +38,14 @@ namespace Kernel
|
|||
auto cmdline_inode = MUST(TmpFileInode::create_new(*s_instance, 0444, 0, 0));
|
||||
MUST(cmdline_inode->write(0, { reinterpret_cast<const uint8_t*>(g_boot_info.command_line.data()), g_boot_info.command_line.size() }));
|
||||
MUST(static_cast<TmpDirectoryInode*>(s_instance->root_inode().ptr())->link_inode(*cmdline_inode, "cmdline"_sv));
|
||||
|
||||
auto self_inode = MUST(ProcSymlinkInode::create_new(
|
||||
[](void*) -> BAN::ErrorOr<BAN::String> {
|
||||
return BAN::String::formatted("{}", Process::current().pid());
|
||||
},
|
||||
nullptr, *s_instance, 0444, 0, 0)
|
||||
);
|
||||
MUST(static_cast<TmpDirectoryInode*>(s_instance->root_inode().ptr())->link_inode(*self_inode, "self"_sv));
|
||||
}
|
||||
|
||||
ProcFileSystem& ProcFileSystem::get()
|
||||
|
|
|
@ -18,6 +18,16 @@ namespace Kernel
|
|||
TRY(inode->link_inode(*MUST(ProcROProcessInode::create_new(process, &Process::proc_cmdline, fs, 0400)), "cmdline"_sv));
|
||||
TRY(inode->link_inode(*MUST(ProcROProcessInode::create_new(process, &Process::proc_environ, fs, 0400)), "environ"_sv));
|
||||
|
||||
TRY(inode->link_inode(*MUST(ProcSymlinkInode::create_new(
|
||||
[](void* process) -> BAN::ErrorOr<BAN::String>
|
||||
{
|
||||
BAN::String result;
|
||||
TRY(result.append(static_cast<Process*>(process)->executable()));
|
||||
return result;
|
||||
},
|
||||
&process, fs, 0400, process.credentials().ruid(), process.credentials().ruid()
|
||||
)), "exe"_sv));
|
||||
|
||||
return inode;
|
||||
}
|
||||
|
||||
|
@ -32,6 +42,7 @@ namespace Kernel
|
|||
(void)TmpDirectoryInode::unlink_impl("meminfo"_sv);
|
||||
(void)TmpDirectoryInode::unlink_impl("cmdline"_sv);
|
||||
(void)TmpDirectoryInode::unlink_impl("environ"_sv);
|
||||
(void)TmpDirectoryInode::unlink_impl("exe"_sv);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<BAN::RefPtr<ProcROProcessInode>> ProcROProcessInode::create_new(Process& process, size_t (Process::*callback)(off_t, BAN::ByteSpan) const, TmpFileSystem& fs, mode_t mode)
|
||||
|
@ -83,4 +94,27 @@ namespace Kernel
|
|||
return m_callback(offset, buffer);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<BAN::RefPtr<ProcSymlinkInode>> ProcSymlinkInode::create_new(BAN::ErrorOr<BAN::String> (*callback)(void*), void* data, TmpFileSystem& fs, mode_t mode, uid_t uid, gid_t gid)
|
||||
{
|
||||
auto inode_info = create_inode_info(Mode::IFLNK | mode, uid, gid);
|
||||
|
||||
auto* inode_ptr = new ProcSymlinkInode(callback, data, fs, inode_info);
|
||||
if (inode_ptr == nullptr)
|
||||
return BAN::Error::from_errno(ENOMEM);
|
||||
return BAN::RefPtr<ProcSymlinkInode>::adopt(inode_ptr);
|
||||
}
|
||||
|
||||
ProcSymlinkInode::ProcSymlinkInode(BAN::ErrorOr<BAN::String> (*callback)(void*), void* data, TmpFileSystem& fs, const TmpInodeInfo& inode_info)
|
||||
: TmpInode(fs, MUST(fs.allocate_inode(inode_info)), inode_info)
|
||||
, m_callback(callback)
|
||||
, m_data(data)
|
||||
{
|
||||
m_inode_info.mode |= Inode::Mode::IFLNK;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<BAN::String> ProcSymlinkInode::link_target_impl()
|
||||
{
|
||||
return m_callback(m_data);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -655,6 +655,20 @@ namespace Kernel
|
|||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> TmpDirectoryInode::link_inode_impl(BAN::StringView name, BAN::RefPtr<Inode> inode)
|
||||
{
|
||||
ASSERT(this->mode().ifdir());
|
||||
ASSERT(!inode->mode().ifdir());
|
||||
ASSERT(&m_fs == inode->filesystem());
|
||||
|
||||
if (!find_inode_impl(name).is_error())
|
||||
return BAN::Error::from_errno(EEXIST);
|
||||
|
||||
auto* tmp_inode = static_cast<TmpInode*>(inode.ptr());
|
||||
TRY(link_inode(*tmp_inode, name));
|
||||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> TmpDirectoryInode::unlink_impl(BAN::StringView name)
|
||||
{
|
||||
ino_t entry_ino = 0;
|
||||
|
|
|
@ -36,6 +36,9 @@ namespace Kernel
|
|||
return BAN::Error::from_errno(ENOMEM);
|
||||
BAN::ScopeGuard _([temp_page] { kfree(temp_page); });
|
||||
|
||||
BAN::String next_file_name;
|
||||
BAN::String next_link_name;
|
||||
|
||||
size_t offset = 0;
|
||||
while (offset + 512 <= module.size)
|
||||
{
|
||||
|
@ -87,12 +90,13 @@ namespace Kernel
|
|||
|
||||
auto parent_inode = filesystem->root_inode();
|
||||
|
||||
auto file_path_parts = TRY(BAN::StringView(file_path).split('/'));
|
||||
auto file_path_parts = TRY(BAN::StringView(next_file_name.empty() ? file_path : next_file_name.sv()).split('/'));
|
||||
for (size_t i = 0; i < file_path_parts.size() - 1; i++)
|
||||
parent_inode = TRY(parent_inode->find_inode(file_path_parts[i]));
|
||||
|
||||
switch (file_type)
|
||||
{
|
||||
case 'L': case 'K': break;
|
||||
case REGTYPE:
|
||||
case AREGTYPE: file_mode |= Inode::Mode::IFREG; break;
|
||||
case LNKTYPE: break;
|
||||
|
@ -102,12 +106,34 @@ namespace Kernel
|
|||
case DIRTYPE: file_mode |= Inode::Mode::IFDIR; break;
|
||||
case FIFOTYPE: file_mode |= Inode::Mode::IFIFO; break;
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
panic("unknown file type {}", file_type);
|
||||
}
|
||||
|
||||
auto file_name_sv = file_path_parts.back();
|
||||
|
||||
if (file_type == DIRTYPE)
|
||||
if (file_type == 'L' || file_type == 'K')
|
||||
{
|
||||
auto& target = (file_type == 'L') ? next_file_name : next_link_name;
|
||||
TRY(target.resize(file_size));
|
||||
|
||||
size_t nwritten = 0;
|
||||
while (nwritten < file_size)
|
||||
{
|
||||
const paddr_t paddr = module.start + offset + 512 + nwritten;
|
||||
PageTable::with_fast_page(paddr & PAGE_ADDR_MASK, [&] {
|
||||
memcpy(temp_page, PageTable::fast_page_as_ptr(), PAGE_SIZE);
|
||||
});
|
||||
|
||||
const size_t page_off = paddr % PAGE_SIZE;
|
||||
const size_t to_write = BAN::Math::min(file_size - nwritten, PAGE_SIZE - page_off);
|
||||
memcpy(target.data() + nwritten, temp_page + page_off, to_write);
|
||||
nwritten += to_write;
|
||||
}
|
||||
|
||||
while (!target.empty() && target.back() == '\0')
|
||||
target.pop_back();
|
||||
}
|
||||
else if (file_type == DIRTYPE)
|
||||
{
|
||||
if (file_name_sv == "."_sv)
|
||||
; // NOTE: don't create "." (root)
|
||||
|
@ -116,7 +142,38 @@ namespace Kernel
|
|||
}
|
||||
else if (file_type == LNKTYPE)
|
||||
{
|
||||
dwarnln("TODO: hardlink");
|
||||
BAN::StringView link_name;
|
||||
|
||||
char link_buffer[101] {};
|
||||
if (!next_link_name.empty())
|
||||
link_name = next_link_name.sv();
|
||||
else
|
||||
{
|
||||
const paddr_t paddr = module.start + offset;
|
||||
PageTable::with_fast_page(paddr & PAGE_ADDR_MASK, [&] {
|
||||
memcpy(link_buffer, PageTable::fast_page_as_ptr((paddr % PAGE_SIZE) + 157), 100);
|
||||
});
|
||||
link_name = link_buffer;
|
||||
}
|
||||
|
||||
auto target_inode = filesystem->root_inode();
|
||||
|
||||
auto link_path_parts = TRY(link_name.split('/'));
|
||||
for (const auto part : link_path_parts)
|
||||
{
|
||||
auto find_result = target_inode->find_inode(part);
|
||||
if (!find_result.is_error())
|
||||
target_inode = find_result.release_value();
|
||||
else
|
||||
{
|
||||
target_inode = {};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (target_inode)
|
||||
if (auto ret = parent_inode->link_inode(file_name_sv, target_inode); ret.is_error())
|
||||
dwarnln("failed to create hardlink '{}': {}", file_name_sv, ret.error());
|
||||
}
|
||||
else if (file_type == SYMTYPE)
|
||||
{
|
||||
|
@ -124,17 +181,22 @@ namespace Kernel
|
|||
dwarnln("failed to create symlink '{}': {}", file_name_sv, ret.error());
|
||||
else
|
||||
{
|
||||
char link_target[101] {};
|
||||
const paddr_t paddr = module.start + offset;
|
||||
PageTable::with_fast_page(paddr & PAGE_ADDR_MASK, [&] {
|
||||
memcpy(link_target, PageTable::fast_page_as_ptr((paddr % PAGE_SIZE) + 157), 100);
|
||||
});
|
||||
BAN::StringView link_name;
|
||||
|
||||
if (link_target[0])
|
||||
char link_buffer[101] {};
|
||||
if (!next_link_name.empty())
|
||||
link_name = next_link_name.sv();
|
||||
else
|
||||
{
|
||||
auto inode = TRY(parent_inode->find_inode(file_name_sv));
|
||||
TRY(inode->set_link_target(link_target));
|
||||
const paddr_t paddr = module.start + offset;
|
||||
PageTable::with_fast_page(paddr & PAGE_ADDR_MASK, [&] {
|
||||
memcpy(link_buffer, PageTable::fast_page_as_ptr((paddr % PAGE_SIZE) + 157), 100);
|
||||
});
|
||||
link_name = link_buffer;
|
||||
}
|
||||
|
||||
auto inode = TRY(parent_inode->find_inode(file_name_sv));
|
||||
TRY(inode->set_link_target(link_name));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -164,6 +226,12 @@ namespace Kernel
|
|||
}
|
||||
}
|
||||
|
||||
if (file_type != 'L' && file_type != 'K')
|
||||
{
|
||||
next_file_name.clear();
|
||||
next_link_name.clear();
|
||||
}
|
||||
|
||||
offset += 512 + file_size;
|
||||
if (auto rem = offset % 512)
|
||||
offset += 512 - rem;
|
||||
|
|
|
@ -174,7 +174,7 @@ namespace Kernel
|
|||
|
||||
MUST(s_instance->mount(root_creds, &ProcFileSystem::get(), "/proc"_sv));
|
||||
|
||||
auto tmpfs = MUST(TmpFileSystem::create(1024, 0777, 0, 0));
|
||||
auto tmpfs = MUST(TmpFileSystem::create(-1, 0777, 0, 0));
|
||||
MUST(s_instance->mount(root_creds, tmpfs, "/tmp"_sv));
|
||||
}
|
||||
|
||||
|
|
|
@ -468,8 +468,8 @@ namespace Kernel::Input
|
|||
TRY(send_command(PS2::Command::DISABLE_SECOND_PORT));
|
||||
|
||||
// Flush The Output Buffer
|
||||
while (!read_byte().is_error())
|
||||
continue;
|
||||
while (IO::inb(m_command_port) & PS2::Status::OUTPUT_STATUS)
|
||||
IO::inb(m_data_port);
|
||||
|
||||
// Set the Controller Configuration Byte
|
||||
TRY(send_command(PS2::Command::READ_CONFIG));
|
||||
|
|
|
@ -13,7 +13,12 @@ namespace Kernel
|
|||
|
||||
if (offset < 0 || offset % PAGE_SIZE || size == 0)
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
if ((size > (size_t)inode->size() || (size_t)offset > (size_t)inode->size() - size))
|
||||
|
||||
size_t inode_size_aligned = inode->size();
|
||||
if (auto rem = inode_size_aligned % PAGE_SIZE)
|
||||
inode_size_aligned += PAGE_SIZE - rem;
|
||||
|
||||
if ((size > inode_size_aligned || static_cast<size_t>(offset) > inode_size_aligned - size))
|
||||
return BAN::Error::from_errno(EOVERFLOW);
|
||||
|
||||
auto* region_ptr = new FileBackedRegion(inode, page_table, offset, size, type, flags, status_flags);
|
||||
|
|
|
@ -132,6 +132,8 @@ namespace Kernel
|
|||
auto executable = TRY(ELF::load_from_inode(process->m_root_file.inode, executable_inode, process->m_credentials, process->page_table()));
|
||||
process->m_mapped_regions = BAN::move(executable.regions);
|
||||
|
||||
TRY(process->m_executable.append(executable_file.canonical_path));
|
||||
|
||||
if (executable_inode->mode().mode & +Inode::Mode::ISUID)
|
||||
process->m_credentials.set_euid(executable_inode->uid());
|
||||
if (executable_inode->mode().mode & +Inode::Mode::ISGID)
|
||||
|
@ -672,6 +674,9 @@ namespace Kernel
|
|||
auto executable = TRY(ELF::load_from_inode(m_root_file.inode, executable_inode, m_credentials, *new_page_table));
|
||||
auto new_mapped_regions = BAN::move(executable.regions);
|
||||
|
||||
BAN::String executable_path;
|
||||
TRY(executable_path.append(executable_file.canonical_path));
|
||||
|
||||
BAN::Vector<LibELF::AuxiliaryVector> auxiliary_vector;
|
||||
TRY(auxiliary_vector.reserve(1 + executable.open_execfd));
|
||||
|
||||
|
@ -712,6 +717,11 @@ namespace Kernel
|
|||
new_thread->set_tls(tls_result.addr);
|
||||
}
|
||||
|
||||
// NOTE: this is done before disabling interrupts and moving the threads as
|
||||
// shared filebacked mmap can write to disk on on clearing, this will lock
|
||||
// filesystem mutex which can yield
|
||||
m_mapped_regions.clear();
|
||||
|
||||
ASSERT(Processor::get_interrupt_state() == InterruptState::Enabled);
|
||||
Processor::set_interrupt_state(InterruptState::Disabled);
|
||||
|
||||
|
@ -756,6 +766,7 @@ namespace Kernel
|
|||
|
||||
m_cmdline = BAN::move(str_argv);
|
||||
m_environ = BAN::move(str_envp);
|
||||
m_executable = BAN::move(executable_path);
|
||||
}
|
||||
|
||||
m_has_called_exec = true;
|
||||
|
@ -1225,7 +1236,8 @@ namespace Kernel
|
|||
{
|
||||
LockGuard _(m_process_lock);
|
||||
TRY(validate_string_access(path1));
|
||||
TRY(validate_string_access(path2));
|
||||
if (path2 != nullptr)
|
||||
TRY(validate_string_access(path2));
|
||||
|
||||
if (!find_file(fd, path2, O_NOFOLLOW).is_error())
|
||||
return BAN::Error::from_errno(EEXIST);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <kernel/InterruptController.h>
|
||||
#include <kernel/Memory/Heap.h>
|
||||
#include <kernel/Memory/kmalloc.h>
|
||||
#include <kernel/Processor.h>
|
||||
#include <kernel/Terminal/TerminalDriver.h>
|
||||
|
@ -47,6 +48,10 @@ namespace Kernel
|
|||
if (s_bsp_id == PROCESSOR_NONE || id == PROCESSOR_NONE || id.m_id >= s_processors.size())
|
||||
Kernel::panic("Trying to initialize invalid processor {}", id.m_id);
|
||||
|
||||
if (id == s_bsp_id)
|
||||
for (auto& processor : s_processors)
|
||||
processor.m_id = PROCESSOR_NONE;
|
||||
|
||||
auto& processor = s_processors[id.m_id];
|
||||
|
||||
ASSERT(processor.m_id == PROCESSOR_NONE);
|
||||
|
@ -64,15 +69,6 @@ namespace Kernel
|
|||
processor.m_scheduler = MUST(Scheduler::create());
|
||||
ASSERT(processor.m_scheduler);
|
||||
|
||||
SMPMessage* smp_storage = new SMPMessage[0x1000];
|
||||
ASSERT(smp_storage);
|
||||
for (size_t i = 0; i < 0xFFF; i++)
|
||||
smp_storage[i].next = &smp_storage[i + 1];
|
||||
smp_storage[0xFFF].next = nullptr;
|
||||
|
||||
processor.m_smp_pending = nullptr;
|
||||
processor.m_smp_free = smp_storage;
|
||||
|
||||
s_processors_created++;
|
||||
|
||||
return processor;
|
||||
|
@ -103,6 +99,34 @@ namespace Kernel
|
|||
return processor;
|
||||
}
|
||||
|
||||
void Processor::initialize_smp()
|
||||
{
|
||||
const auto processor_id = current_id();
|
||||
auto& processor = s_processors[processor_id.as_u32()];
|
||||
|
||||
const paddr_t smp_paddr = Heap::get().take_free_page();
|
||||
ASSERT(smp_paddr);
|
||||
|
||||
const vaddr_t smp_vaddr = PageTable::kernel().reserve_free_page(KERNEL_OFFSET);
|
||||
ASSERT(smp_vaddr);
|
||||
|
||||
PageTable::kernel().map_page_at(
|
||||
smp_paddr, smp_vaddr,
|
||||
PageTable::Flags::ReadWrite | PageTable::Flags::Present,
|
||||
PageTable::MemoryType::Uncached
|
||||
);
|
||||
|
||||
auto* smp_storage = reinterpret_cast<SMPMessage*>(smp_vaddr);
|
||||
|
||||
constexpr size_t smp_storage_entries = PAGE_SIZE / sizeof(SMPMessage);
|
||||
for (size_t i = 0; i < smp_storage_entries - 1; i++)
|
||||
smp_storage[i].next = &smp_storage[i + 1];
|
||||
smp_storage[smp_storage_entries - 1].next = nullptr;
|
||||
|
||||
processor.m_smp_pending = nullptr;
|
||||
processor.m_smp_free = smp_storage;
|
||||
}
|
||||
|
||||
ProcessorID Processor::id_from_index(size_t index)
|
||||
{
|
||||
ASSERT(index < s_processor_count);
|
||||
|
@ -112,12 +136,7 @@ namespace Kernel
|
|||
|
||||
void Processor::wait_until_processors_ready()
|
||||
{
|
||||
if (s_processors_created == 1)
|
||||
{
|
||||
ASSERT(current_is_bsp());
|
||||
s_processor_count++;
|
||||
s_processor_ids[0] = current_id();
|
||||
}
|
||||
initialize_smp();
|
||||
|
||||
// wait until bsp is ready
|
||||
if (current_is_bsp())
|
||||
|
@ -178,21 +197,6 @@ namespace Kernel
|
|||
handle_smp_messages();
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void with_atomic_lock(BAN::Atomic<bool>& lock, F callback)
|
||||
{
|
||||
bool expected = false;
|
||||
while (!lock.compare_exchange(expected, true, BAN::MemoryOrder::memory_order_acquire))
|
||||
{
|
||||
__builtin_ia32_pause();
|
||||
expected = false;
|
||||
}
|
||||
|
||||
callback();
|
||||
|
||||
lock.store(false, BAN::MemoryOrder::memory_order_release);
|
||||
}
|
||||
|
||||
void Processor::handle_smp_messages()
|
||||
{
|
||||
auto state = get_interrupt_state();
|
||||
|
@ -201,65 +205,61 @@ namespace Kernel
|
|||
auto processor_id = current_id();
|
||||
auto& processor = s_processors[processor_id.m_id];
|
||||
|
||||
SMPMessage* pending = nullptr;
|
||||
with_atomic_lock(processor.m_smp_pending_lock,
|
||||
[&]()
|
||||
{
|
||||
pending = processor.m_smp_pending;
|
||||
processor.m_smp_pending = nullptr;
|
||||
}
|
||||
);
|
||||
auto* pending = processor.m_smp_pending.exchange(nullptr);
|
||||
if (pending == nullptr)
|
||||
return set_interrupt_state(state);
|
||||
|
||||
if (pending)
|
||||
// reverse smp message queue from LIFO to FIFO
|
||||
{
|
||||
// reverse smp message queue from LIFO to FIFO
|
||||
SMPMessage* reversed = nullptr;
|
||||
|
||||
for (auto* message = pending; message;)
|
||||
{
|
||||
SMPMessage* reversed = nullptr;
|
||||
|
||||
for (SMPMessage* message = pending; message;)
|
||||
{
|
||||
SMPMessage* next = message->next;
|
||||
message->next = reversed;
|
||||
reversed = message;
|
||||
message = next;
|
||||
}
|
||||
|
||||
pending = reversed;
|
||||
SMPMessage* next = message->next;
|
||||
message->next = reversed;
|
||||
reversed = message;
|
||||
message = next;
|
||||
}
|
||||
|
||||
SMPMessage* last_handled = nullptr;
|
||||
pending = reversed;
|
||||
}
|
||||
|
||||
// handle messages
|
||||
for (auto* message = pending; message; message = message->next)
|
||||
SMPMessage* last_handled = nullptr;
|
||||
|
||||
// handle messages
|
||||
for (auto* message = pending; message; message = message->next)
|
||||
{
|
||||
switch (message->type)
|
||||
{
|
||||
switch (message->type)
|
||||
{
|
||||
case SMPMessage::Type::FlushTLB:
|
||||
for (size_t i = 0; i < message->flush_tlb.page_count; i++)
|
||||
asm volatile("invlpg (%0)" :: "r"(message->flush_tlb.vaddr + i * PAGE_SIZE) : "memory");
|
||||
break;
|
||||
case SMPMessage::Type::NewThread:
|
||||
processor.m_scheduler->add_thread(message->new_thread);
|
||||
break;
|
||||
case SMPMessage::Type::UnblockThread:
|
||||
processor.m_scheduler->unblock_thread(message->unblock_thread);
|
||||
break;
|
||||
case SMPMessage::Type::StackTrace:
|
||||
dwarnln("Stack trace of CPU {}", current_id().as_u32());
|
||||
Debug::dump_stack_trace();
|
||||
break;
|
||||
}
|
||||
|
||||
last_handled = message;
|
||||
case SMPMessage::Type::FlushTLB:
|
||||
for (size_t i = 0; i < message->flush_tlb.page_count; i++)
|
||||
asm volatile("invlpg (%0)" :: "r"(message->flush_tlb.vaddr + i * PAGE_SIZE) : "memory");
|
||||
break;
|
||||
case SMPMessage::Type::NewThread:
|
||||
processor.m_scheduler->add_thread(message->new_thread);
|
||||
break;
|
||||
case SMPMessage::Type::UnblockThread:
|
||||
processor.m_scheduler->unblock_thread(message->unblock_thread);
|
||||
break;
|
||||
#if WITH_PROFILING
|
||||
case SMPMessage::Type::StartProfiling:
|
||||
processor.start_profiling();
|
||||
break;
|
||||
#endif
|
||||
case SMPMessage::Type::StackTrace:
|
||||
dwarnln("Stack trace of CPU {}", current_id().as_u32());
|
||||
Debug::dump_stack_trace();
|
||||
break;
|
||||
}
|
||||
|
||||
with_atomic_lock(processor.m_smp_free_lock,
|
||||
[&]()
|
||||
{
|
||||
last_handled->next = processor.m_smp_free;
|
||||
processor.m_smp_free = pending;
|
||||
}
|
||||
);
|
||||
last_handled = message;
|
||||
}
|
||||
|
||||
last_handled->next = processor.m_smp_free;
|
||||
while (!processor.m_smp_free.compare_exchange(last_handled->next, pending))
|
||||
{
|
||||
__builtin_ia32_pause();
|
||||
last_handled->next = processor.m_smp_free;
|
||||
}
|
||||
|
||||
set_interrupt_state(state);
|
||||
|
@ -279,35 +279,49 @@ namespace Kernel
|
|||
|
||||
void Processor::send_smp_message(ProcessorID processor_id, const SMPMessage& message, bool send_ipi)
|
||||
{
|
||||
|
||||
auto state = get_interrupt_state();
|
||||
set_interrupt_state(InterruptState::Disabled);
|
||||
|
||||
auto& processor = s_processors[processor_id.m_id];
|
||||
|
||||
// take free message slot
|
||||
SMPMessage* storage = nullptr;
|
||||
with_atomic_lock(processor.m_smp_free_lock,
|
||||
[&]()
|
||||
{
|
||||
storage = processor.m_smp_free;
|
||||
ASSERT(storage && storage->next);
|
||||
// find a slot for message
|
||||
auto* storage = processor.m_smp_free.exchange(nullptr);
|
||||
while (storage == nullptr)
|
||||
{
|
||||
__builtin_ia32_pause();
|
||||
storage = processor.m_smp_free.exchange(nullptr);
|
||||
}
|
||||
|
||||
processor.m_smp_free = storage->next;
|
||||
if (auto* base = storage->next)
|
||||
{
|
||||
SMPMessage* null = nullptr;
|
||||
if (!processor.m_smp_free.compare_exchange(null, base))
|
||||
{
|
||||
// NOTE: this is an annoying traversal, but most of the time
|
||||
// above if condition bypasses this :)
|
||||
auto* last = base;
|
||||
while (last->next)
|
||||
last = last->next;
|
||||
|
||||
last->next = processor.m_smp_free;
|
||||
while (!processor.m_smp_free.compare_exchange(last->next, base))
|
||||
{
|
||||
__builtin_ia32_pause();
|
||||
last->next = processor.m_smp_free;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// write message
|
||||
*storage = message;
|
||||
|
||||
// push message to pending queue
|
||||
with_atomic_lock(processor.m_smp_pending_lock,
|
||||
[&]()
|
||||
{
|
||||
storage->next = processor.m_smp_pending;
|
||||
processor.m_smp_pending = storage;
|
||||
}
|
||||
);
|
||||
storage->next = processor.m_smp_pending;
|
||||
while (!processor.m_smp_pending.compare_exchange(storage->next, storage))
|
||||
{
|
||||
__builtin_ia32_pause();
|
||||
storage->next = processor.m_smp_pending;
|
||||
}
|
||||
|
||||
if (send_ipi)
|
||||
{
|
||||
|
|
|
@ -573,13 +573,24 @@ namespace Kernel
|
|||
{
|
||||
// Make sure stack is allocated
|
||||
|
||||
const vaddr_t pages[3] {
|
||||
(interrupt_stack.sp - sizeof(uintptr_t)) & PAGE_ADDR_MASK,
|
||||
(signal_stack_top - 4 * sizeof(uintptr_t)) & PAGE_ADDR_MASK,
|
||||
(signal_stack_top - 1 * sizeof(uintptr_t)) & PAGE_ADDR_MASK,
|
||||
};
|
||||
vaddr_t pages[3] {};
|
||||
size_t page_count { 0 };
|
||||
|
||||
for (size_t i = 0; i < 3; i++)
|
||||
if (signal_stack_top == 0)
|
||||
{
|
||||
pages[0] = (interrupt_stack.sp - 1 * sizeof(uintptr_t)) & PAGE_ADDR_MASK;
|
||||
pages[1] = (interrupt_stack.sp - 5 * sizeof(uintptr_t)) & PAGE_ADDR_MASK;
|
||||
page_count = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
pages[0] = (interrupt_stack.sp - sizeof(uintptr_t)) & PAGE_ADDR_MASK;
|
||||
pages[1] = (signal_stack_top - 4 * sizeof(uintptr_t)) & PAGE_ADDR_MASK;
|
||||
pages[2] = (signal_stack_top - 1 * sizeof(uintptr_t)) & PAGE_ADDR_MASK;
|
||||
page_count = 3;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < page_count; i++)
|
||||
{
|
||||
if (m_process->page_table().get_page_flags(pages[i]) & PageTable::Flags::Present)
|
||||
continue;
|
||||
|
@ -782,6 +793,8 @@ namespace Kernel
|
|||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
Processor::set_interrupt_state(InterruptState::Disabled);
|
||||
m_state = State::Terminated;
|
||||
Processor::yield();
|
||||
ASSERT_NOT_REACHED();
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='gcc'
|
||||
VERSION='15.1.0'
|
||||
DOWNLOAD_URL="https://ftp.gnu.org/gnu/gcc/gcc-$VERSION/gcc-$VERSION.tar.gz#51b9919ea69c980d7a381db95d4be27edf73b21254eb13d752a08003b4d013b1"
|
||||
VERSION='15.2.0'
|
||||
DOWNLOAD_URL="https://ftp.gnu.org/gnu/gcc/gcc-$VERSION/gcc-$VERSION.tar.xz#438fd996826b0c82485a29da03a72d71d6e3541a83ec702df4271f6fe025d24e"
|
||||
DEPENDENCIES=('binutils' 'gmp' 'mpfr' 'mpc')
|
||||
MAKE_BUILD_TARGETS=('all-gcc' 'all-target-libgcc' 'all-target-libstdc++-v3')
|
||||
MAKE_INSTALL_TARGETS=('install-strip-gcc' 'install-strip-target-libgcc' 'install-strip-target-libstdc++-v3')
|
||||
CONFIGURE_OPTIONS=(
|
||||
"--target=$BANAN_TOOLCHAIN_TRIPLE"
|
||||
|
@ -18,6 +17,17 @@ CONFIGURE_OPTIONS=(
|
|||
'--enable-languages=c,c++'
|
||||
)
|
||||
|
||||
build() {
|
||||
xcflags=""
|
||||
if [ $BANAN_ARCH = "x86_64" ]; then
|
||||
xcflags="-mcmodel=large -mno-red-zone"
|
||||
fi
|
||||
|
||||
make -j$(nproc) all-gcc || exit 1
|
||||
make -j$(nproc) all-target-libgcc CFLAGS_FOR_TARGET="$xcflags" || exit 1
|
||||
make -j$(nproc) all-target-libstdc++-v3 || exit 1
|
||||
}
|
||||
|
||||
post_install() {
|
||||
# remove libtool files
|
||||
rm -f $BANAN_SYSROOT/usr/lib/libstdc++.la
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
../../../toolchain/gcc-15.1.0.patch
|
|
@ -0,0 +1 @@
|
|||
../../../toolchain/gcc-15.2.0.patch
|
|
@ -59,8 +59,9 @@ config_sub_update() {
|
|||
|
||||
config_sub_path="$BANAN_PORT_DIR/config.sub"
|
||||
|
||||
if [ ! -f "$config_sub_path" ] || [ $(find "$config_sub_path" -mtime +1) ]; then
|
||||
wget -O "$config_sub_path" 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD'
|
||||
if [ ! -f "$config_sub_path" ]; then
|
||||
wget -O "$config_sub_path.tmp" 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD' || exit 1
|
||||
mv $config_sub_path.tmp $config_sub_path
|
||||
fi
|
||||
|
||||
for target in "${CONFIG_SUB[@]}"; do
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
diff -ruN binutils-2.45/bfd/config.bfd binutils-2.45-banan_os/bfd/config.bfd
|
||||
--- binutils-2.45/bfd/config.bfd 2025-07-27 02:00:00.000000000 +0300
|
||||
+++ binutils-2.45-banan_os/bfd/config.bfd 2025-08-25 17:59:50.309772929 +0300
|
||||
@@ -612,6 +612,11 @@
|
||||
targ_defvec=i386_elf32_vec
|
||||
targ_selvecs=iamcu_elf32_vec
|
||||
;;
|
||||
+ i[3-7]86-*-banan_os*)
|
||||
+ targ_defvec=i386_elf32_vec
|
||||
+ targ_selvecs=
|
||||
+ targ64_selvecs=x86_64_elf64_vec
|
||||
+ ;;
|
||||
i[3-7]86-*-dicos*)
|
||||
targ_defvec=i386_elf32_vec
|
||||
targ_selvecs=iamcu_elf32_vec
|
||||
@@ -666,6 +671,11 @@
|
||||
targ64_selvecs=x86_64_elf64_vec
|
||||
;;
|
||||
#ifdef BFD64
|
||||
+ x86_64-*-banan_os*)
|
||||
+ targ_defvec=x86_64_elf64_vec
|
||||
+ targ_selvecs=i386_elf32_vec
|
||||
+ want64=true
|
||||
+ ;;
|
||||
x86_64-*-cloudabi*)
|
||||
targ_defvec=x86_64_elf64_cloudabi_vec
|
||||
want64=true
|
||||
diff -ruN binutils-2.45/config.sub binutils-2.45-banan_os/config.sub
|
||||
--- binutils-2.45/config.sub 2025-07-27 02:00:00.000000000 +0300
|
||||
+++ binutils-2.45-banan_os/config.sub 2025-08-25 17:59:50.310634287 +0300
|
||||
@@ -1976,6 +1976,7 @@
|
||||
| atheos* \
|
||||
| auroraux* \
|
||||
| aux* \
|
||||
+ | banan_os* \
|
||||
| beos* \
|
||||
| bitrig* \
|
||||
| bme* \
|
||||
diff -ruN binutils-2.45/gas/configure.tgt binutils-2.45-banan_os/gas/configure.tgt
|
||||
--- binutils-2.45/gas/configure.tgt 2025-07-27 02:00:00.000000000 +0300
|
||||
+++ binutils-2.45-banan_os/gas/configure.tgt 2025-08-25 17:59:50.311092868 +0300
|
||||
@@ -225,6 +225,7 @@
|
||||
h8300-*-elf) fmt=elf ;;
|
||||
h8300-*-linux*) fmt=elf em=linux ;;
|
||||
|
||||
+ i386-*-banan_os*) fmt=elf em=gnu ;;
|
||||
i386-*-beospe*) fmt=coff em=pe ;;
|
||||
i386-*-beos*) fmt=elf ;;
|
||||
i386-*-elfiamcu) fmt=elf arch=iamcu ;;
|
||||
diff -ruN binutils-2.45/ld/configure.tgt binutils-2.45-banan_os/ld/configure.tgt
|
||||
--- binutils-2.45/ld/configure.tgt 2025-07-27 02:00:00.000000000 +0300
|
||||
+++ binutils-2.45-banan_os/ld/configure.tgt 2025-08-25 17:59:50.311577500 +0300
|
||||
@@ -367,6 +367,10 @@
|
||||
i[3-7]86-*-rdos*) targ_emul=elf_i386
|
||||
targ_extra_emuls=elf_iamcu
|
||||
;;
|
||||
+i[3-7]86-*-banan_os*) targ_emul=elf_i386_banan_os
|
||||
+ targ_extra_emuls=elf_i386
|
||||
+ targ64_extra_emuls="elf_x86_64_banan_os elf_x86_64"
|
||||
+ ;;
|
||||
i[3-7]86-*-bsd) targ_emul=i386bsd
|
||||
targ_extra_ofiles=
|
||||
;;
|
||||
@@ -1000,6 +1004,9 @@
|
||||
;;
|
||||
x86_64-*-rdos*) targ_emul=elf64rdos
|
||||
;;
|
||||
+x86_64-*-banan_os*) targ_emul=elf_x86_64_banan_os
|
||||
+ targ_extra_emuls="elf_i386_banan_os elf_x86_64 elf_i386"
|
||||
+ ;;
|
||||
x86_64-*-cloudabi*) targ_emul=elf_x86_64_cloudabi
|
||||
;;
|
||||
x86_64-*-haiku*) targ_emul=elf_x86_64_haiku
|
||||
diff -ruN binutils-2.45/ld/emulparams/elf_banan_os.sh binutils-2.45-banan_os/ld/emulparams/elf_banan_os.sh
|
||||
--- binutils-2.45/ld/emulparams/elf_banan_os.sh 1970-01-01 02:00:00.000000000 +0200
|
||||
+++ binutils-2.45-banan_os/ld/emulparams/elf_banan_os.sh 2025-08-25 17:59:50.312097122 +0300
|
||||
@@ -0,0 +1 @@
|
||||
+ELF_INTERPRETER_NAME=\"/usr/lib/DynamicLoader.so\"
|
||||
diff -ruN binutils-2.45/ld/emulparams/elf_i386_banan_os.sh binutils-2.45-banan_os/ld/emulparams/elf_i386_banan_os.sh
|
||||
--- binutils-2.45/ld/emulparams/elf_i386_banan_os.sh 1970-01-01 02:00:00.000000000 +0200
|
||||
+++ binutils-2.45-banan_os/ld/emulparams/elf_i386_banan_os.sh 2025-08-25 17:59:50.312315308 +0300
|
||||
@@ -0,0 +1,2 @@
|
||||
+source_sh ${srcdir}/emulparams/elf_i386.sh
|
||||
+source_sh ${srcdir}/emulparams/elf_banan_os.sh
|
||||
diff -ruN binutils-2.45/ld/emulparams/elf_x86_64_banan_os.sh binutils-2.45-banan_os/ld/emulparams/elf_x86_64_banan_os.sh
|
||||
--- binutils-2.45/ld/emulparams/elf_x86_64_banan_os.sh 1970-01-01 02:00:00.000000000 +0200
|
||||
+++ binutils-2.45-banan_os/ld/emulparams/elf_x86_64_banan_os.sh 2025-08-25 17:59:50.312553817 +0300
|
||||
@@ -0,0 +1,2 @@
|
||||
+source_sh ${srcdir}/emulparams/elf_x86_64.sh
|
||||
+source_sh ${srcdir}/emulparams/elf_banan_os.sh
|
||||
diff -ruN binutils-2.45/ld/Makefile.am binutils-2.45-banan_os/ld/Makefile.am
|
||||
--- binutils-2.45/ld/Makefile.am 2025-07-27 02:00:00.000000000 +0300
|
||||
+++ binutils-2.45-banan_os/ld/Makefile.am 2025-08-25 17:59:50.312853718 +0300
|
||||
@@ -277,6 +277,7 @@
|
||||
eelf32xtensa.c \
|
||||
eelf32z80.c \
|
||||
eelf_i386.c \
|
||||
+ eelf_i386_banan_os.c \
|
||||
eelf_i386_be.c \
|
||||
eelf_i386_fbsd.c \
|
||||
eelf_i386_haiku.c \
|
||||
@@ -459,6 +460,7 @@
|
||||
eelf64tilegx_be.c \
|
||||
eelf_mipsel_haiku.c \
|
||||
eelf_x86_64.c \
|
||||
+ eelf_x86_64_banan_os.c \
|
||||
eelf_x86_64_cloudabi.c \
|
||||
eelf_x86_64_fbsd.c \
|
||||
eelf_x86_64_haiku.c \
|
||||
diff -ruN binutils-2.45/ld/Makefile.in binutils-2.45-banan_os/ld/Makefile.in
|
||||
--- binutils-2.45/ld/Makefile.in 2025-07-27 02:00:00.000000000 +0300
|
||||
+++ binutils-2.45-banan_os/ld/Makefile.in 2025-08-25 17:59:50.313554579 +0300
|
||||
@@ -788,6 +788,7 @@
|
||||
eelf32xtensa.c \
|
||||
eelf32z80.c \
|
||||
eelf_i386.c \
|
||||
+ eelf_i386_banan_os.c \
|
||||
eelf_i386_be.c \
|
||||
eelf_i386_fbsd.c \
|
||||
eelf_i386_haiku.c \
|
||||
@@ -969,6 +970,7 @@
|
||||
eelf64tilegx_be.c \
|
||||
eelf_mipsel_haiku.c \
|
||||
eelf_x86_64.c \
|
||||
+ eelf_x86_64_banan_os.c \
|
||||
eelf_x86_64_cloudabi.c \
|
||||
eelf_x86_64_fbsd.c \
|
||||
eelf_x86_64_haiku.c \
|
||||
@@ -1476,6 +1478,7 @@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64tilegx.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64tilegx_be.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386.Po@am__quote@
|
||||
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_banan_os.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_be.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_fbsd.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_haiku.Po@am__quote@
|
||||
@@ -1486,6 +1489,7 @@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_mipsel_haiku.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_s390.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64.Po@am__quote@
|
||||
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_banan_os.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_cloudabi.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_fbsd.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_haiku.Po@am__quote@
|
|
@ -1,12 +1,12 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
BINUTILS_VERSION="binutils-2.44"
|
||||
BINUTILS_TAR="$BINUTILS_VERSION.tar.gz"
|
||||
BINUTILS_VERSION="binutils-2.45"
|
||||
BINUTILS_TAR="$BINUTILS_VERSION.tar.xz"
|
||||
BINUTILS_URL="https://ftp.gnu.org/gnu/binutils/$BINUTILS_TAR"
|
||||
|
||||
GCC_VERSION="gcc-15.1.0"
|
||||
GCC_TAR="$GCC_VERSION.tar.gz"
|
||||
GCC_VERSION="gcc-15.2.0"
|
||||
GCC_TAR="$GCC_VERSION.tar.xz"
|
||||
GCC_URL="https://ftp.gnu.org/gnu/gcc/$GCC_VERSION/$GCC_TAR"
|
||||
|
||||
GRUB_VERSION="grub-2.06"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
diff -ruN gcc-15.1.0/config.sub gcc-15.1.0-banan_os/config.sub
|
||||
--- gcc-15.1.0/config.sub 2025-04-25 11:17:59.000000000 +0300
|
||||
+++ gcc-15.1.0-banan_os/config.sub 2025-06-19 11:29:44.368548733 +0300
|
||||
diff -ruN gcc-15.2.0/config.sub gcc-15.2.0-banan_os/config.sub
|
||||
--- gcc-15.2.0/config.sub 2025-08-25 18:08:25.524209333 +0300
|
||||
+++ gcc-15.2.0-banan_os/config.sub 2025-08-25 18:09:09.160072736 +0300
|
||||
@@ -1749,7 +1749,7 @@
|
||||
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
|
||||
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
|
||||
|
@ -10,9 +10,9 @@ diff -ruN gcc-15.1.0/config.sub gcc-15.1.0-banan_os/config.sub
|
|||
;;
|
||||
# This one is extra strict with allowed versions
|
||||
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
|
||||
diff -ruN gcc-15.1.0/fixincludes/mkfixinc.sh gcc-15.1.0-banan_os/fixincludes/mkfixinc.sh
|
||||
--- gcc-15.1.0/fixincludes/mkfixinc.sh 2025-04-25 11:17:59.000000000 +0300
|
||||
+++ gcc-15.1.0-banan_os/fixincludes/mkfixinc.sh 2025-06-19 11:30:13.427343038 +0300
|
||||
diff -ruN gcc-15.2.0/fixincludes/mkfixinc.sh gcc-15.2.0-banan_os/fixincludes/mkfixinc.sh
|
||||
--- gcc-15.2.0/fixincludes/mkfixinc.sh 2025-08-25 18:08:42.043663414 +0300
|
||||
+++ gcc-15.2.0-banan_os/fixincludes/mkfixinc.sh 2025-08-25 18:09:09.191771254 +0300
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
# Check for special fix rules for particular targets
|
||||
|
@ -21,9 +21,9 @@ diff -ruN gcc-15.1.0/fixincludes/mkfixinc.sh gcc-15.1.0-banan_os/fixincludes/mkf
|
|||
i?86-*-cygwin* | \
|
||||
*-mingw32* | \
|
||||
powerpc-*-eabisim* | \
|
||||
diff -ruN gcc-15.1.0/gcc/config/banan_os.h gcc-15.1.0-banan_os/gcc/config/banan_os.h
|
||||
--- gcc-15.1.0/gcc/config/banan_os.h 1970-01-01 02:00:00.000000000 +0200
|
||||
+++ gcc-15.1.0-banan_os/gcc/config/banan_os.h 2025-06-19 11:30:53.316059523 +0300
|
||||
diff -ruN gcc-15.2.0/gcc/config/banan_os.h gcc-15.2.0-banan_os/gcc/config/banan_os.h
|
||||
--- gcc-15.2.0/gcc/config/banan_os.h 1970-01-01 02:00:00.000000000 +0200
|
||||
+++ gcc-15.2.0-banan_os/gcc/config/banan_os.h 2025-08-25 18:09:09.192159227 +0300
|
||||
@@ -0,0 +1,35 @@
|
||||
+/* Useful if you wish to make target-specific GCC changes. */
|
||||
+#undef TARGET_BANAN_OS
|
||||
|
@ -60,9 +60,9 @@ diff -ruN gcc-15.1.0/gcc/config/banan_os.h gcc-15.1.0-banan_os/gcc/config/banan_
|
|||
+ builtin_assert ("system=unix"); \
|
||||
+ builtin_assert ("system=posix"); \
|
||||
+ } while(0);
|
||||
diff -ruN gcc-15.1.0/gcc/config/banan_os.opt gcc-15.1.0-banan_os/gcc/config/banan_os.opt
|
||||
--- gcc-15.1.0/gcc/config/banan_os.opt 1970-01-01 02:00:00.000000000 +0200
|
||||
+++ gcc-15.1.0-banan_os/gcc/config/banan_os.opt 2025-06-19 11:31:29.325802503 +0300
|
||||
diff -ruN gcc-15.2.0/gcc/config/banan_os.opt gcc-15.2.0-banan_os/gcc/config/banan_os.opt
|
||||
--- gcc-15.2.0/gcc/config/banan_os.opt 1970-01-01 02:00:00.000000000 +0200
|
||||
+++ gcc-15.2.0-banan_os/gcc/config/banan_os.opt 2025-08-25 18:09:09.192299819 +0300
|
||||
@@ -0,0 +1,32 @@
|
||||
+; banan_os options.
|
||||
+
|
||||
|
@ -96,14 +96,14 @@ diff -ruN gcc-15.1.0/gcc/config/banan_os.opt gcc-15.1.0-banan_os/gcc/config/bana
|
|||
+Driver
|
||||
+
|
||||
+; This comment is to ensure we retain the blank line above.
|
||||
diff -ruN gcc-15.1.0/gcc/config/banan_os.opt.urls gcc-15.1.0-banan_os/gcc/config/banan_os.opt.urls
|
||||
--- gcc-15.1.0/gcc/config/banan_os.opt.urls 1970-01-01 02:00:00.000000000 +0200
|
||||
+++ gcc-15.1.0-banan_os/gcc/config/banan_os.opt.urls 2025-06-19 11:31:29.325802503 +0300
|
||||
diff -ruN gcc-15.2.0/gcc/config/banan_os.opt.urls gcc-15.2.0-banan_os/gcc/config/banan_os.opt.urls
|
||||
--- gcc-15.2.0/gcc/config/banan_os.opt.urls 1970-01-01 02:00:00.000000000 +0200
|
||||
+++ gcc-15.2.0-banan_os/gcc/config/banan_os.opt.urls 2025-08-25 18:09:09.192460665 +0300
|
||||
@@ -0,0 +1 @@
|
||||
+; Not sure what to put here but this works
|
||||
diff -ruN gcc-15.1.0/gcc/config.gcc gcc-15.1.0-banan_os/gcc/config.gcc
|
||||
--- gcc-15.1.0/gcc/config.gcc 2025-04-25 11:18:00.000000000 +0300
|
||||
+++ gcc-15.1.0-banan_os/gcc/config.gcc 2025-06-19 11:32:50.391220522 +0300
|
||||
diff -ruN gcc-15.2.0/gcc/config.gcc gcc-15.2.0-banan_os/gcc/config.gcc
|
||||
--- gcc-15.2.0/gcc/config.gcc 2025-08-25 18:08:36.953184232 +0300
|
||||
+++ gcc-15.2.0-banan_os/gcc/config.gcc 2025-08-25 18:09:09.193116622 +0300
|
||||
@@ -723,6 +723,14 @@
|
||||
|
||||
# Common parts for widely ported systems.
|
||||
|
@ -132,9 +132,9 @@ diff -ruN gcc-15.1.0/gcc/config.gcc gcc-15.1.0-banan_os/gcc/config.gcc
|
|||
i[34567]86-*-dragonfly*)
|
||||
tm_file="${tm_file} i386/unix.h i386/att.h elfos.h dragonfly.h dragonfly-stdint.h i386/dragonfly.h"
|
||||
tmake_file="${tmake_file} i386/t-crtstuff"
|
||||
diff -ruN gcc-15.1.0/libgcc/config/t-slibgcc gcc-15.1.0-banan_os/libgcc/config/t-slibgcc
|
||||
--- gcc-15.1.0/libgcc/config/t-slibgcc 2025-04-25 11:18:04.000000000 +0300
|
||||
+++ gcc-15.1.0-banan_os/libgcc/config/t-slibgcc 2025-06-19 11:34:04.674683603 +0300
|
||||
diff -ruN gcc-15.2.0/libgcc/config/t-slibgcc gcc-15.2.0-banan_os/libgcc/config/t-slibgcc
|
||||
--- gcc-15.2.0/libgcc/config/t-slibgcc 2025-08-25 18:08:42.538268318 +0300
|
||||
+++ gcc-15.2.0-banan_os/libgcc/config/t-slibgcc 2025-08-25 18:09:09.206796796 +0300
|
||||
@@ -26,7 +26,6 @@
|
||||
SHLIB_OBJS = @shlib_objs@
|
||||
SHLIB_DIR = @multilib_dir@
|
||||
|
@ -143,9 +143,9 @@ diff -ruN gcc-15.1.0/libgcc/config/t-slibgcc gcc-15.1.0-banan_os/libgcc/config/t
|
|||
SHLIB_MAKE_SOLINK = $(LN_S) $(SHLIB_SONAME) $(SHLIB_DIR)/$(SHLIB_SOLINK)
|
||||
SHLIB_INSTALL_SOLINK = $(LN_S) $(SHLIB_SONAME) \
|
||||
$(DESTDIR)$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK)
|
||||
diff -ruN gcc-15.1.0/libgcc/config.host gcc-15.1.0-banan_os/libgcc/config.host
|
||||
--- gcc-15.1.0/libgcc/config.host 2025-04-25 11:18:04.000000000 +0300
|
||||
+++ gcc-15.1.0-banan_os/libgcc/config.host 2025-06-19 11:33:42.354845264 +0300
|
||||
diff -ruN gcc-15.2.0/libgcc/config.host gcc-15.2.0-banan_os/libgcc/config.host
|
||||
--- gcc-15.2.0/libgcc/config.host 2025-08-25 18:08:42.103193239 +0300
|
||||
+++ gcc-15.2.0-banan_os/libgcc/config.host 2025-08-25 18:09:09.221444143 +0300
|
||||
@@ -627,6 +627,14 @@
|
||||
fixed_point=no
|
||||
fi
|
||||
|
@ -161,9 +161,9 @@ diff -ruN gcc-15.1.0/libgcc/config.host gcc-15.1.0-banan_os/libgcc/config.host
|
|||
bfin*-elf*)
|
||||
tmake_file="bfin/t-bfin bfin/t-crtlibid bfin/t-crtstuff t-libgcc-pic t-fdpbit"
|
||||
extra_parts="$extra_parts crtbeginS.o crtendS.o crti.o crtn.o crtlibid.o"
|
||||
diff -ruN gcc-15.1.0/libstdc++-v3/acinclude.m4 gcc-15.1.0-banan_os/libstdc++-v3/acinclude.m4
|
||||
--- gcc-15.1.0/libstdc++-v3/acinclude.m4 2025-04-25 11:18:05.000000000 +0300
|
||||
+++ gcc-15.1.0-banan_os/libstdc++-v3/acinclude.m4 2025-06-19 11:34:58.939289470 +0300
|
||||
diff -ruN gcc-15.2.0/libstdc++-v3/acinclude.m4 gcc-15.2.0-banan_os/libstdc++-v3/acinclude.m4
|
||||
--- gcc-15.2.0/libstdc++-v3/acinclude.m4 2025-08-25 18:08:44.358147732 +0300
|
||||
+++ gcc-15.2.0-banan_os/libstdc++-v3/acinclude.m4 2025-08-25 18:09:09.241116556 +0300
|
||||
@@ -1792,7 +1792,7 @@
|
||||
ac_has_nanosleep=yes
|
||||
ac_has_sched_yield=yes
|
||||
|
@ -173,10 +173,10 @@ diff -ruN gcc-15.1.0/libstdc++-v3/acinclude.m4 gcc-15.1.0-banan_os/libstdc++-v3/
|
|||
ac_has_clock_monotonic=yes
|
||||
ac_has_clock_realtime=yes
|
||||
ac_has_nanosleep=yes
|
||||
diff -ruN gcc-15.1.0/libstdc++-v3/configure gcc-15.1.0-banan_os/libstdc++-v3/configure
|
||||
--- gcc-15.1.0/libstdc++-v3/configure 2025-04-25 11:18:05.000000000 +0300
|
||||
+++ gcc-15.1.0-banan_os/libstdc++-v3/configure 2025-06-19 11:37:41.265102481 +0300
|
||||
@@ -15789,8 +15789,8 @@ if test "$enable_shared" = yes; then
|
||||
diff -ruN gcc-15.2.0/libstdc++-v3/configure gcc-15.2.0-banan_os/libstdc++-v3/configure
|
||||
--- gcc-15.2.0/libstdc++-v3/configure 2025-08-25 18:08:47.550144038 +0300
|
||||
+++ gcc-15.2.0-banan_os/libstdc++-v3/configure 2025-08-25 18:09:09.262116528 +0300
|
||||
@@ -15784,8 +15784,8 @@
|
||||
glibcxx_compiler_shared_flag="-D_GLIBCXX_SHARED"
|
||||
|
||||
else
|
||||
|
@ -205,9 +205,9 @@ diff -ruN gcc-15.1.0/libstdc++-v3/configure gcc-15.1.0-banan_os/libstdc++-v3/con
|
|||
$as_echo "#define HAVE_ACOSF 1" >>confdefs.h
|
||||
|
||||
$as_echo "#define HAVE_ASINF 1" >>confdefs.h
|
||||
diff -ruN gcc-15.1.0/libstdc++-v3/crossconfig.m4 gcc-15.1.0-banan_os/libstdc++-v3/crossconfig.m4
|
||||
--- gcc-15.1.0/libstdc++-v3/crossconfig.m4 2025-04-25 11:18:05.000000000 +0300
|
||||
+++ gcc-15.1.0-banan_os/libstdc++-v3/crossconfig.m4 2025-06-19 11:36:53.954449540 +0300
|
||||
diff -ruN gcc-15.2.0/libstdc++-v3/crossconfig.m4 gcc-15.2.0-banan_os/libstdc++-v3/crossconfig.m4
|
||||
--- gcc-15.2.0/libstdc++-v3/crossconfig.m4 2025-08-25 18:08:47.570807934 +0300
|
||||
+++ gcc-15.2.0-banan_os/libstdc++-v3/crossconfig.m4 2025-08-25 18:09:09.263116526 +0300
|
||||
@@ -9,7 +9,7 @@
|
||||
# This is a freestanding configuration; there is nothing to do here.
|
||||
;;
|
|
@ -48,7 +48,7 @@ sigsetjmp:
|
|||
|
||||
subq $8, %rsp
|
||||
movq %rdi, (%rsp)
|
||||
leaq 72(%rsi), %rdx
|
||||
leaq 72(%rdi), %rdx
|
||||
xorq %rsi, %rsi
|
||||
call pthread_sigmask
|
||||
movq (%rsp), %rdi
|
||||
|
|
|
@ -34,11 +34,7 @@ struct FILE
|
|||
unsigned char unget_buffer[12];
|
||||
uint32_t unget_buf_idx;
|
||||
|
||||
// TODO: use recursive pthread_mutex when implemented?
|
||||
// this storage hack is to keep FILE pod (init order)
|
||||
BAN::Atomic<pthread_t>& locker() { return *reinterpret_cast<BAN::Atomic<pthread_t>*>(locker_storage); }
|
||||
unsigned char locker_storage[sizeof(pthread_t)];
|
||||
uint32_t lock_depth;
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
static_assert(BAN::is_pod_v<FILE>);
|
||||
|
||||
|
@ -98,9 +94,11 @@ static void _init_stdio()
|
|||
{
|
||||
init_closed_file(&s_files[i]);
|
||||
|
||||
new (&s_files[i].locker()) BAN::Atomic<pthread_t>();
|
||||
s_files[i].locker() = -1;
|
||||
s_files[i].lock_depth = 0;
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&s_files[i].mutex, &attr);
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
}
|
||||
|
||||
s_files[STDIN_FILENO].fd = STDIN_FILENO;
|
||||
|
@ -313,22 +311,6 @@ int fileno(FILE* fp)
|
|||
return fp->fd;
|
||||
}
|
||||
|
||||
void flockfile(FILE* fp)
|
||||
{
|
||||
const pthread_t tid = pthread_self();
|
||||
|
||||
pthread_t expected = -1;
|
||||
while (!fp->locker().compare_exchange(expected, tid, BAN::MemoryOrder::memory_order_acq_rel))
|
||||
{
|
||||
if (expected == tid)
|
||||
break;
|
||||
sched_yield();
|
||||
expected = -1;
|
||||
}
|
||||
|
||||
fp->lock_depth++;
|
||||
}
|
||||
|
||||
FILE* fopen(const char* pathname, const char* mode_str)
|
||||
{
|
||||
mode_t mode = parse_mode_string(mode_str);
|
||||
|
@ -485,25 +467,19 @@ off_t ftello(FILE* file)
|
|||
return offset - file->unget_buf_idx;
|
||||
}
|
||||
|
||||
void flockfile(FILE* fp)
|
||||
{
|
||||
pthread_mutex_lock(&fp->mutex);
|
||||
}
|
||||
|
||||
int ftrylockfile(FILE* fp)
|
||||
{
|
||||
const pthread_t tid = pthread_self();
|
||||
|
||||
pthread_t expected = -1;
|
||||
if (!fp->locker().compare_exchange(expected, tid, BAN::MemoryOrder::memory_order_acq_rel))
|
||||
if (expected != tid)
|
||||
return 1;
|
||||
|
||||
fp->lock_depth++;
|
||||
return 0;
|
||||
return pthread_mutex_trylock(&fp->mutex);
|
||||
}
|
||||
|
||||
void funlockfile(FILE* fp)
|
||||
{
|
||||
ASSERT(fp->locker() == pthread_self());
|
||||
ASSERT(fp->lock_depth > 0);
|
||||
if (--fp->lock_depth == 0)
|
||||
fp->locker().store(-1, BAN::MemoryOrder::memory_order_release);
|
||||
pthread_mutex_unlock(&fp->mutex);
|
||||
}
|
||||
|
||||
size_t fwrite(const void* buffer, size_t size, size_t nitems, FILE* file)
|
||||
|
@ -803,11 +779,17 @@ int putc_unlocked(int c, FILE* file)
|
|||
return (unsigned char)c;
|
||||
}
|
||||
|
||||
if (file->buffer_idx >= file->buffer_size)
|
||||
if (fflush(file) == EOF)
|
||||
return EOF;
|
||||
|
||||
file->buffer[file->buffer_idx] = c;
|
||||
file->buffer_idx++;
|
||||
|
||||
if ((file->buffer_type == _IOLBF && c == '\n') || file->buffer_idx >= file->buffer_size)
|
||||
if (fflush(file) == EOF)
|
||||
return EOF;
|
||||
|
||||
return (unsigned char)c;
|
||||
}
|
||||
|
||||
|
@ -875,6 +857,9 @@ int rename(const char* old, const char* _new)
|
|||
}
|
||||
}
|
||||
|
||||
close(new_fd);
|
||||
close(old_fd);
|
||||
|
||||
unlink(old);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -27,6 +27,8 @@ static BAN::ErrorOr<long long> read_integer_from_file(const char* file)
|
|||
static BAN::String get_battery_percentage()
|
||||
{
|
||||
DIR* dirp = opendir("/dev/batteries");
|
||||
if (dirp == nullptr)
|
||||
return {};
|
||||
|
||||
BAN::String result;
|
||||
while (dirent* dirent = readdir(dirp))
|
||||
|
@ -53,6 +55,8 @@ static BAN::String get_battery_percentage()
|
|||
(void)result.append(string.value());
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue