ELFLoader: Do not keep track of segments
This reduces calls to kmalloc() since segment data is heap-allocated, and the segments loaded will be deleted when deleting the page directory.
This commit is contained in:
parent
f0e14cf7e9
commit
d3c414af4e
@ -23,19 +23,11 @@ static bool can_write_segment(u32 flags)
|
|||||||
return can_write_segment(flags) && can_execute_segment(flags);
|
return can_write_segment(flags) && can_execute_segment(flags);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
ELFSegment::ELFSegment(u64 base, usize size) : m_base(base), m_size(size)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace ELFLoader
|
namespace ELFLoader
|
||||||
{
|
{
|
||||||
// FIXME: Check that all calls to read_contents() read the proper amount of bytes.
|
// FIXME: Check that all calls to read_contents() read the proper amount of bytes.
|
||||||
Result<ELFData> load(const TarStream::Entry& elf_entry, const TarStream& stream)
|
Result<ELFData> load(const TarStream::Entry& elf_entry, const TarStream& stream)
|
||||||
{
|
{
|
||||||
LinkedList<ELFSegment> segments;
|
|
||||||
|
|
||||||
auto guard = make_scope_guard([&] { segments.consume([](ELFSegment* segment) { delete segment; }); });
|
|
||||||
|
|
||||||
Elf64_Ehdr elf_header;
|
Elf64_Ehdr elf_header;
|
||||||
usize nread = stream.read_contents(elf_entry, &elf_header, 0, sizeof elf_header);
|
usize nread = stream.read_contents(elf_entry, &elf_header, 0, sizeof elf_header);
|
||||||
if (nread < sizeof elf_header)
|
if (nread < sizeof elf_header)
|
||||||
@ -101,9 +93,6 @@ namespace ELFLoader
|
|||||||
/*expect(!can_write_and_execute_segment(program_header.p_flags),
|
/*expect(!can_write_and_execute_segment(program_header.p_flags),
|
||||||
"Segment is both writable and executable");*/
|
"Segment is both writable and executable");*/
|
||||||
|
|
||||||
ELFSegment* segment = TRY(make<ELFSegment>(program_header.p_vaddr, program_header.p_memsz));
|
|
||||||
segments.append(segment);
|
|
||||||
|
|
||||||
int flags = MMU::User | MMU::NoExecute;
|
int flags = MMU::User | MMU::NoExecute;
|
||||||
if (can_write_segment(program_header.p_flags)) flags |= MMU::ReadWrite;
|
if (can_write_segment(program_header.p_flags)) flags |= MMU::ReadWrite;
|
||||||
else if (can_execute_segment(program_header.p_flags))
|
else if (can_execute_segment(program_header.p_flags))
|
||||||
@ -124,14 +113,6 @@ namespace ELFLoader
|
|||||||
else { kdbgln("ELF: Encountered non-loadable program header, skipping"); }
|
else { kdbgln("ELF: Encountered non-loadable program header, skipping"); }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (segments.count() == 0)
|
return ELFData { elf_header.e_entry };
|
||||||
{
|
|
||||||
kdbgln("Error while loading ELF: No loadable segments");
|
|
||||||
return err(ENOEXEC);
|
|
||||||
}
|
|
||||||
|
|
||||||
guard.deactivate();
|
|
||||||
|
|
||||||
return ELFData { segments, elf_header.e_entry };
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,28 +47,8 @@ typedef struct
|
|||||||
u64 p_align; /* Segment alignment */
|
u64 p_align; /* Segment alignment */
|
||||||
} Elf64_Phdr;
|
} Elf64_Phdr;
|
||||||
|
|
||||||
struct ELFSegment : public LinkedListNode<ELFSegment>
|
|
||||||
{
|
|
||||||
u64 base() const
|
|
||||||
{
|
|
||||||
return m_base;
|
|
||||||
}
|
|
||||||
|
|
||||||
usize size() const
|
|
||||||
{
|
|
||||||
return m_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
ELFSegment(u64 base, usize size);
|
|
||||||
|
|
||||||
private:
|
|
||||||
u64 m_base;
|
|
||||||
usize m_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ELFData
|
struct ELFData
|
||||||
{
|
{
|
||||||
LinkedList<ELFSegment> segments;
|
|
||||||
u64 entry;
|
u64 entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user