Kernel: Pass interpreter base address in auxiliary vector

This commit is contained in:
2026-06-26 01:51:21 +03:00
parent fc1a6cacdc
commit 9919cbf66e
4 changed files with 18 additions and 6 deletions

View File

@@ -14,8 +14,8 @@ namespace Kernel::ELF
size_t size;
};
bool open_execfd;
vaddr_t entry_point;
BAN::Optional<vaddr_t> interp_base;
BAN::Optional<TLS> master_tls;
BAN::Vector<BAN::UniqPtr<MemoryRegion>> regions;
};

View File

@@ -291,7 +291,9 @@ namespace Kernel::ELF
TRY(memory_regions.emplace_back(BAN::move(region)));
}
result.open_execfd = !interpreter.empty();
if (!interpreter.empty())
result.interp_base = load_base_vaddr;
result.entry_point = load_base_vaddr + file_header.e_entry;
result.regions = BAN::move(memory_regions);
return BAN::move(result);

View File

@@ -144,15 +144,19 @@ namespace Kernel
process->m_credentials.set_egid(executable_inode->gid());
BAN::Vector<LibELF::AuxiliaryVector> auxiliary_vector;
TRY(auxiliary_vector.reserve(1 + executable.open_execfd));
TRY(auxiliary_vector.reserve(2 + 2 * executable.interp_base.has_value()));
if (executable.open_execfd)
if (executable.interp_base.has_value())
{
const int execfd = TRY(process->m_open_file_descriptors.open(BAN::move(executable_file), O_RDONLY));
TRY(auxiliary_vector.push_back({
.a_type = LibELF::AT_EXECFD,
.a_un = { .a_val = static_cast<uint32_t>(execfd) },
}));
TRY(auxiliary_vector.push_back({
.a_type = LibELF::AT_BASE,
.a_un = { .a_ptr = reinterpret_cast<void*>(executable.interp_base.value()) },
}));
}
process->m_shared_page_vaddr = process->page_table().reserve_free_page(process->m_mapped_regions.back()->vaddr(), USERSPACE_END);
@@ -821,7 +825,7 @@ namespace Kernel
TRY(executable_path.append(executable_file.canonical_path));
BAN::Vector<LibELF::AuxiliaryVector> auxiliary_vector;
TRY(auxiliary_vector.reserve(1 + executable.open_execfd));
TRY(auxiliary_vector.reserve(2 + 2 * executable.interp_base.has_value()));
BAN::ScopeGuard execfd_guard([this, &auxiliary_vector] {
if (auxiliary_vector.empty())
@@ -831,13 +835,17 @@ namespace Kernel
MUST(m_open_file_descriptors.close(auxiliary_vector.front().a_un.a_val));
});
if (executable.open_execfd)
if (executable.interp_base.has_value())
{
const int execfd = TRY(m_open_file_descriptors.open(BAN::move(executable_file), O_RDONLY));
TRY(auxiliary_vector.push_back({
.a_type = LibELF::AT_EXECFD,
.a_un = { .a_val = static_cast<uint32_t>(execfd) },
}));
TRY(auxiliary_vector.push_back({
.a_type = LibELF::AT_BASE,
.a_un = { .a_ptr = reinterpret_cast<void*>(executable.interp_base.value()) },
}));
}
const vaddr_t shared_page_vaddr = new_page_table->reserve_free_page(new_mapped_regions.back()->vaddr(), USERSPACE_END);