Compare commits
5 Commits
50ab391133
...
2ae2ede0b2
Author | SHA1 | Date |
---|---|---|
Bananymous | 2ae2ede0b2 | |
Bananymous | ef5af384e7 | |
Bananymous | a134d16070 | |
Bananymous | 827eec6af0 | |
Bananymous | 8da2f12ba6 |
|
@ -211,7 +211,7 @@ elseif("${BANAN_ARCH}" STREQUAL "i686")
|
|||
target_link_options(kernel PRIVATE LINKER:-T,${CMAKE_CURRENT_SOURCE_DIR}/arch/i686/linker.ld)
|
||||
endif()
|
||||
|
||||
target_link_options(kernel PRIVATE -ffreestanding -nostdlib)
|
||||
target_link_options(kernel PRIVATE -ffreestanding -nostdlib -orphan-handling=error)
|
||||
|
||||
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=crtbegin.o OUTPUT_VARIABLE CRTBEGIN OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=crtend.o OUTPUT_VARIABLE CRTEND OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
|
|
@ -21,20 +21,20 @@ SECTIONS
|
|||
g_userspace_end = .;
|
||||
g_kernel_execute_end = .;
|
||||
}
|
||||
.ap_init ALIGN(4K) : AT(ADDR(.ap_init))
|
||||
.ap_init ALIGN(4K) : AT(ADDR(.ap_init) - KERNEL_OFFSET)
|
||||
{
|
||||
g_ap_init_addr = .;
|
||||
*(.ap_init)
|
||||
}
|
||||
.rodata ALIGN(4K) : AT(ADDR(.rodata) - KERNEL_OFFSET)
|
||||
{
|
||||
*(.rodata.*)
|
||||
}
|
||||
.data ALIGN(4K) : AT(ADDR(.data) - KERNEL_OFFSET)
|
||||
{
|
||||
g_kernel_writable_start = .;
|
||||
*(.data)
|
||||
}
|
||||
.rodata ALIGN(4K) : AT(ADDR(.rodata) - KERNEL_OFFSET)
|
||||
{
|
||||
*(.rodata.*)
|
||||
}
|
||||
.bss ALIGN(4K) : AT(ADDR(.bss) - KERNEL_OFFSET)
|
||||
{
|
||||
*(COMMON)
|
||||
|
|
|
@ -21,20 +21,20 @@ SECTIONS
|
|||
g_userspace_end = .;
|
||||
g_kernel_execute_end = .;
|
||||
}
|
||||
.ap_init ALIGN(4K) : AT(ADDR(.ap_init))
|
||||
.ap_init ALIGN(4K) : AT(ADDR(.ap_init) - KERNEL_OFFSET)
|
||||
{
|
||||
g_ap_init_addr = .;
|
||||
*(.ap_init)
|
||||
}
|
||||
.rodata ALIGN(4K) : AT(ADDR(.rodata) - KERNEL_OFFSET)
|
||||
{
|
||||
*(.rodata.*)
|
||||
}
|
||||
.data ALIGN(4K) : AT(ADDR(.data) - KERNEL_OFFSET)
|
||||
{
|
||||
g_kernel_writable_start = .;
|
||||
*(.data)
|
||||
}
|
||||
.rodata ALIGN(4K) : AT(ADDR(.rodata) - KERNEL_OFFSET)
|
||||
{
|
||||
*(.rodata.*)
|
||||
}
|
||||
.bss ALIGN(4K) : AT(ADDR(.bss) - KERNEL_OFFSET)
|
||||
{
|
||||
*(COMMON)
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace Kernel
|
|||
|
||||
bool MemoryRegion::contains_fully(vaddr_t address, size_t size) const
|
||||
{
|
||||
return m_vaddr <= address && address + size < m_vaddr + m_size;
|
||||
return m_vaddr <= address && address + size <= m_vaddr + m_size;
|
||||
}
|
||||
|
||||
bool MemoryRegion::overlaps(vaddr_t address, size_t size) const
|
||||
|
|
|
@ -519,8 +519,8 @@ namespace Kernel
|
|||
{
|
||||
VirtualFileSystem::File file;
|
||||
TRY(file.canonical_path.append("<self>"));
|
||||
file.inode = m_loadable_elf->inode();
|
||||
m_userspace_info.file_fd = TRY(m_open_file_descriptors.open(BAN::move(file), O_EXEC));
|
||||
file.inode = m_loadable_elf->executable();
|
||||
m_userspace_info.file_fd = TRY(m_open_file_descriptors.open(BAN::move(file), O_RDONLY));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sizeof(m_signal_handlers) / sizeof(*m_signal_handlers); i++)
|
||||
|
@ -2376,7 +2376,7 @@ namespace Kernel
|
|||
return {};
|
||||
|
||||
unauthorized_access:
|
||||
dwarnln("process {}, thread {} attempted to make an invalid pointer access", pid(), Thread::current().tid());
|
||||
dwarnln("process {}, thread {} attempted to make an invalid pointer access to 0x{H}->0x{H}", pid(), Thread::current().tid(), vaddr, vaddr + size);
|
||||
Debug::dump_stack_trace();
|
||||
MUST(sys_kill(pid(), SIGSEGV));
|
||||
return BAN::Error::from_errno(EINTR);
|
||||
|
|
|
@ -26,10 +26,10 @@ namespace LibELF
|
|||
|
||||
LoadableELF::~LoadableELF()
|
||||
{
|
||||
const auto cleanup_program_headers =
|
||||
[&](BAN::Span<const ElfNativeProgramHeader> headers)
|
||||
{
|
||||
for (const auto& header : headers)
|
||||
if (!m_is_loaded)
|
||||
return;
|
||||
|
||||
for (const auto& header : m_program_headers)
|
||||
{
|
||||
ASSERT(header.p_type == PT_LOAD);
|
||||
|
||||
|
@ -40,12 +40,6 @@ namespace LibELF
|
|||
Heap::get().release_page(paddr);
|
||||
m_page_table.unmap_range(vaddr, pages * PAGE_SIZE);
|
||||
}
|
||||
};
|
||||
|
||||
if (!m_is_loaded)
|
||||
return;
|
||||
cleanup_program_headers(m_executable.program_headers.span());
|
||||
cleanup_program_headers(m_interpreter.program_headers.span());
|
||||
}
|
||||
|
||||
static BAN::ErrorOr<ElfNativeFileHeader> read_and_validate_file_header(BAN::RefPtr<Inode> inode)
|
||||
|
@ -166,30 +160,26 @@ namespace LibELF
|
|||
}
|
||||
|
||||
return LoadResult {
|
||||
.elf_file = {
|
||||
.inode = inode,
|
||||
.interp = interp,
|
||||
.file_header = file_header,
|
||||
.program_headers = BAN::move(program_headers),
|
||||
.dynamic_base = 0
|
||||
},
|
||||
.interp = interp
|
||||
.program_headers = BAN::move(program_headers)
|
||||
};
|
||||
}
|
||||
|
||||
bool LoadableELF::does_executable_and_interpreter_overlap() const
|
||||
static bool do_program_headers_overlap(BAN::Span<const ElfNativeProgramHeader> pheaders1, BAN::Span<const ElfNativeProgramHeader> pheaders2, vaddr_t base2)
|
||||
{
|
||||
ASSERT(m_executable.inode);
|
||||
ASSERT(m_interpreter.inode);
|
||||
for (const auto& pheader1 : pheaders1)
|
||||
{
|
||||
for (const auto& pheader2 : pheaders2)
|
||||
{
|
||||
const vaddr_t s1 = pheader1.p_vaddr & PAGE_ADDR_MASK;
|
||||
const vaddr_t e1 = (pheader1.p_vaddr + pheader1.p_memsz + PAGE_SIZE - 1) & PAGE_ADDR_MASK;
|
||||
|
||||
for (const auto& epheader : m_executable.program_headers)
|
||||
{
|
||||
for (const auto& ipheader : m_interpreter.program_headers)
|
||||
{
|
||||
const vaddr_t e1 = epheader.p_vaddr & PAGE_ADDR_MASK;
|
||||
const vaddr_t i1 = ipheader.p_vaddr & PAGE_ADDR_MASK;
|
||||
const vaddr_t e2 = (epheader.p_vaddr + epheader.p_memsz + PAGE_SIZE - 1) & PAGE_ADDR_MASK;
|
||||
const vaddr_t i2 = (ipheader.p_vaddr + ipheader.p_memsz + PAGE_SIZE - 1) & PAGE_ADDR_MASK;
|
||||
if (e1 < i2 && i1 < e2)
|
||||
const vaddr_t s2 = pheader2.p_vaddr & PAGE_ADDR_MASK;
|
||||
const vaddr_t e2 = (pheader2.p_vaddr + pheader2.p_memsz + PAGE_SIZE - 1) & PAGE_ADDR_MASK;
|
||||
|
||||
if (s1 < e2 + base2 && s2 + base2 < e1)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -199,74 +189,95 @@ namespace LibELF
|
|||
|
||||
BAN::ErrorOr<void> LoadableELF::initialize(const Credentials& credentials, BAN::RefPtr<Inode> inode)
|
||||
{
|
||||
const auto generate_random_dynamic_base =
|
||||
[]() -> vaddr_t
|
||||
{
|
||||
// 1 MiB -> 2 GiB + 1 MiB
|
||||
return (Random::get_u32() & 0x7FFFF000) + 0x100000;
|
||||
};
|
||||
|
||||
|
||||
auto executable_load_result = TRY(load_elf_file(credentials, inode));
|
||||
m_executable = executable_load_result.elf_file;
|
||||
|
||||
if (m_executable.file_header.e_type == ET_DYN)
|
||||
m_executable = executable_load_result.inode;
|
||||
m_interpreter = executable_load_result.interp;
|
||||
|
||||
vaddr_t dynamic_base = 0;
|
||||
|
||||
if (m_interpreter)
|
||||
{
|
||||
m_executable.dynamic_base = (Random::get_u32() & 0x7FFFF000) + 0x100000;
|
||||
m_executable.file_header.e_entry += m_executable.dynamic_base;
|
||||
for (auto& program_header : m_executable.program_headers)
|
||||
program_header.p_vaddr += m_executable.dynamic_base;
|
||||
}
|
||||
|
||||
if (executable_load_result.interp)
|
||||
{
|
||||
auto interp_load_result = TRY(load_elf_file(credentials, executable_load_result.interp));
|
||||
m_interpreter = interp_load_result.elf_file;
|
||||
|
||||
auto interp_load_result = TRY(load_elf_file(credentials, m_interpreter));
|
||||
if (interp_load_result.interp)
|
||||
{
|
||||
dwarnln("Executable has specified interpreter for its interpreter");
|
||||
dwarnln("ELF interpreter has an interpreter");
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
|
||||
if (m_interpreter.file_header.e_type == ET_DYN)
|
||||
if (executable_load_result.file_header.e_type == ET_EXEC)
|
||||
{
|
||||
if (interp_load_result.file_header.e_type == ET_EXEC)
|
||||
{
|
||||
const bool has_overlap = do_program_headers_overlap(
|
||||
executable_load_result.program_headers.span(),
|
||||
interp_load_result.program_headers.span(),
|
||||
0
|
||||
);
|
||||
|
||||
if (has_overlap)
|
||||
{
|
||||
dwarnln("Executable and interpreter LOAD segments overlap");
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int attempt = 0; attempt < 100; attempt++)
|
||||
{
|
||||
const vaddr_t dynamic_base = (Random::get_u32() & 0x3FFFF000) + 0x40000000;
|
||||
for (auto& program_header : m_interpreter.program_headers)
|
||||
program_header.p_vaddr += dynamic_base;
|
||||
if (does_executable_and_interpreter_overlap())
|
||||
{
|
||||
for (auto& program_header : m_interpreter.program_headers)
|
||||
program_header.p_vaddr -= dynamic_base;
|
||||
const vaddr_t test_dynamic_base = generate_random_dynamic_base();
|
||||
const bool has_overlap = do_program_headers_overlap(
|
||||
executable_load_result.program_headers.span(),
|
||||
interp_load_result.program_headers.span(),
|
||||
test_dynamic_base
|
||||
);
|
||||
if (has_overlap)
|
||||
continue;
|
||||
}
|
||||
m_interpreter.dynamic_base = dynamic_base;
|
||||
m_interpreter.file_header.e_entry += dynamic_base;
|
||||
dynamic_base = test_dynamic_base;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const bool can_load_interpreter = (m_interpreter.file_header.e_type == ET_DYN)
|
||||
? (m_interpreter.dynamic_base != 0)
|
||||
: !does_executable_and_interpreter_overlap();
|
||||
|
||||
if (!can_load_interpreter)
|
||||
if (dynamic_base == 0)
|
||||
{
|
||||
dwarnln("Could not find space to load interpreter");
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_file_header = interp_load_result.file_header;
|
||||
m_program_headers = BAN::move(interp_load_result.program_headers);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_file_header = executable_load_result.file_header;
|
||||
m_program_headers = BAN::move(executable_load_result.program_headers);
|
||||
}
|
||||
|
||||
if (m_file_header.e_type == ET_DYN && dynamic_base == 0)
|
||||
dynamic_base = generate_random_dynamic_base();
|
||||
|
||||
if (dynamic_base)
|
||||
{
|
||||
m_file_header.e_entry += dynamic_base;
|
||||
for (auto& program_header : m_program_headers)
|
||||
program_header.p_vaddr += dynamic_base;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
vaddr_t LoadableELF::entry_point() const
|
||||
{
|
||||
if (m_interpreter.inode)
|
||||
return m_interpreter.file_header.e_entry;
|
||||
return m_executable.file_header.e_entry;
|
||||
}
|
||||
|
||||
bool LoadableELF::contains(vaddr_t address) const
|
||||
{
|
||||
for (const auto& program_header : m_executable.program_headers)
|
||||
if (program_header.p_vaddr <= address && address < program_header.p_vaddr + program_header.p_memsz)
|
||||
return true;
|
||||
for (const auto& program_header : m_interpreter.program_headers)
|
||||
for (const auto& program_header : m_program_headers)
|
||||
if (program_header.p_vaddr <= address && address < program_header.p_vaddr + program_header.p_memsz)
|
||||
return true;
|
||||
return false;
|
||||
|
@ -274,10 +285,7 @@ namespace LibELF
|
|||
|
||||
bool LoadableELF::is_address_space_free() const
|
||||
{
|
||||
const auto are_program_headers_free =
|
||||
[&](BAN::Span<const ElfNativeProgramHeader> program_headers) -> bool
|
||||
{
|
||||
for (const auto& program_header : program_headers)
|
||||
for (const auto& program_header : m_program_headers)
|
||||
{
|
||||
ASSERT(program_header.p_type == PT_LOAD);
|
||||
const vaddr_t page_vaddr = program_header.p_vaddr & PAGE_ADDR_MASK;
|
||||
|
@ -286,20 +294,11 @@ namespace LibELF
|
|||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
if (!are_program_headers_free(m_executable.program_headers.span()))
|
||||
return false;
|
||||
if (!are_program_headers_free(m_interpreter.program_headers.span()))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void LoadableELF::reserve_address_space()
|
||||
{
|
||||
const auto reserve_program_headers =
|
||||
[&](BAN::Span<const ElfNativeProgramHeader> program_headers)
|
||||
{
|
||||
for (const auto& program_header : program_headers)
|
||||
for (const auto& program_header : m_program_headers)
|
||||
{
|
||||
ASSERT(program_header.p_type == PT_LOAD);
|
||||
const vaddr_t page_vaddr = program_header.p_vaddr & PAGE_ADDR_MASK;
|
||||
|
@ -308,29 +307,24 @@ namespace LibELF
|
|||
ASSERT_NOT_REACHED();
|
||||
m_virtual_page_count += pages;
|
||||
}
|
||||
};
|
||||
reserve_program_headers(m_executable.program_headers.span());
|
||||
reserve_program_headers(m_interpreter.program_headers.span());
|
||||
m_is_loaded = true;
|
||||
}
|
||||
|
||||
void LoadableELF::update_suid_sgid(Kernel::Credentials& credentials)
|
||||
{
|
||||
auto inode = m_executable.inode;
|
||||
ASSERT(inode);
|
||||
|
||||
if (inode->mode().mode & +Inode::Mode::ISUID)
|
||||
credentials.set_euid(inode->uid());
|
||||
if (inode->mode().mode & +Inode::Mode::ISGID)
|
||||
credentials.set_egid(inode->gid());
|
||||
if (m_executable->mode().mode & +Inode::Mode::ISUID)
|
||||
credentials.set_euid(m_executable->uid());
|
||||
if (m_executable->mode().mode & +Inode::Mode::ISGID)
|
||||
credentials.set_egid(m_executable->gid());
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> LoadableELF::load_page_to_memory(vaddr_t address)
|
||||
{
|
||||
const auto load_page_from_program_header =
|
||||
[&](BAN::RefPtr<Inode> inode, BAN::Span<const ElfNativeProgramHeader> program_headers) -> BAN::ErrorOr<bool>
|
||||
{
|
||||
for (const auto& program_header : program_headers)
|
||||
auto inode = has_interpreter() ? m_interpreter : m_executable;
|
||||
|
||||
// FIXME: use MemoryBackedRegion/FileBackedRegion instead of manually mapping and allocating pages
|
||||
|
||||
for (const auto& program_header : m_program_headers)
|
||||
{
|
||||
ASSERT(program_header.p_type == PT_LOAD);
|
||||
if (!(program_header.p_vaddr <= address && address < program_header.p_vaddr + program_header.p_memsz))
|
||||
|
@ -370,16 +364,9 @@ namespace LibELF
|
|||
// Map page with the correct flags
|
||||
m_page_table.map_page_at(paddr, vaddr, flags);
|
||||
|
||||
return true;
|
||||
return {};
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
if (TRY(load_page_from_program_header(m_executable.inode, m_executable.program_headers.span())))
|
||||
return {};
|
||||
if (TRY(load_page_from_program_header(m_interpreter.inode, m_interpreter.program_headers.span())))
|
||||
return {};
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
|
@ -387,27 +374,16 @@ namespace LibELF
|
|||
{
|
||||
auto elf = TRY(BAN::UniqPtr<LoadableELF>::create(new_page_table));
|
||||
|
||||
const auto clone_loadable_file =
|
||||
[](const LoadableElfFile& source, LoadableElfFile& destination) -> BAN::ErrorOr<void>
|
||||
{
|
||||
if (!source.inode)
|
||||
return {};
|
||||
elf->m_executable = m_executable;
|
||||
elf->m_interpreter = m_interpreter;
|
||||
elf->m_file_header = m_file_header;
|
||||
TRY(elf->m_program_headers.reserve(m_program_headers.size()));
|
||||
for (const auto& program_header : m_program_headers)
|
||||
MUST(elf->m_program_headers.emplace_back(program_header));
|
||||
|
||||
destination.inode = source.inode;
|
||||
destination.file_header = source.file_header;
|
||||
destination.dynamic_base = source.dynamic_base;
|
||||
elf->reserve_address_space();
|
||||
|
||||
TRY(destination.program_headers.reserve(source.program_headers.size()));
|
||||
for (const auto& program_header : source.program_headers)
|
||||
MUST(destination.program_headers.emplace_back(program_header));
|
||||
|
||||
return {};
|
||||
};
|
||||
|
||||
const auto map_loadable_file =
|
||||
[&](BAN::Span<const ElfNativeProgramHeader> program_headers) -> BAN::ErrorOr<void>
|
||||
{
|
||||
for (const auto& program_header : program_headers)
|
||||
for (const auto& program_header : m_program_headers)
|
||||
{
|
||||
ASSERT(program_header.p_type == PT_LOAD);
|
||||
if (!(program_header.p_flags & LibELF::PF_W))
|
||||
|
@ -439,16 +415,6 @@ namespace LibELF
|
|||
elf->m_physical_page_count++;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
};
|
||||
|
||||
TRY(clone_loadable_file(m_executable, elf->m_executable));
|
||||
TRY(clone_loadable_file(m_interpreter, elf->m_interpreter));
|
||||
|
||||
elf->reserve_address_space();
|
||||
|
||||
TRY(map_loadable_file(elf->m_executable.program_headers.span()));
|
||||
TRY(map_loadable_file(elf->m_interpreter.program_headers.span()));
|
||||
|
||||
return elf;
|
||||
}
|
||||
|
|
|
@ -25,10 +25,10 @@ namespace LibELF
|
|||
static BAN::ErrorOr<BAN::UniqPtr<LoadableELF>> load_from_inode(Kernel::PageTable&, const Kernel::Credentials&, BAN::RefPtr<Kernel::Inode>);
|
||||
~LoadableELF();
|
||||
|
||||
Kernel::vaddr_t entry_point() const;
|
||||
Kernel::vaddr_t entry_point() const { return m_file_header.e_entry; }
|
||||
|
||||
bool has_interpreter() const { return !!m_interpreter.inode; }
|
||||
BAN::RefPtr<Kernel::Inode> inode() { return m_executable.inode; }
|
||||
bool has_interpreter() const { return !!m_interpreter; }
|
||||
BAN::RefPtr<Kernel::Inode> executable() { return m_executable; }
|
||||
|
||||
bool contains(Kernel::vaddr_t address) const;
|
||||
bool is_address_space_free() const;
|
||||
|
@ -44,30 +44,25 @@ namespace LibELF
|
|||
size_t physical_page_count() const { return m_physical_page_count; }
|
||||
|
||||
private:
|
||||
struct LoadableElfFile
|
||||
{
|
||||
BAN::RefPtr<Kernel::Inode> inode;
|
||||
ElfNativeFileHeader file_header;
|
||||
BAN::Vector<ElfNativeProgramHeader> program_headers;
|
||||
Kernel::vaddr_t dynamic_base;
|
||||
};
|
||||
|
||||
struct LoadResult
|
||||
{
|
||||
LoadableElfFile elf_file;
|
||||
BAN::RefPtr<Kernel::Inode> inode;
|
||||
BAN::RefPtr<Kernel::Inode> interp;
|
||||
ElfNativeFileHeader file_header;
|
||||
BAN::Vector<ElfNativeProgramHeader> program_headers;
|
||||
};
|
||||
|
||||
private:
|
||||
LoadableELF(Kernel::PageTable&);
|
||||
BAN::ErrorOr<void> initialize(const Kernel::Credentials&, BAN::RefPtr<Kernel::Inode>);
|
||||
|
||||
bool does_executable_and_interpreter_overlap() const;
|
||||
BAN::ErrorOr<LoadResult> load_elf_file(const Kernel::Credentials&, BAN::RefPtr<Kernel::Inode>) const;
|
||||
|
||||
private:
|
||||
LoadableElfFile m_executable;
|
||||
LoadableElfFile m_interpreter;
|
||||
BAN::RefPtr<Kernel::Inode> m_executable;
|
||||
BAN::RefPtr<Kernel::Inode> m_interpreter;
|
||||
ElfNativeFileHeader m_file_header;
|
||||
BAN::Vector<ElfNativeProgramHeader> m_program_headers;
|
||||
|
||||
Kernel::PageTable& m_page_table;
|
||||
size_t m_virtual_page_count { 0 };
|
||||
size_t m_physical_page_count { 0 };
|
||||
|
|
|
@ -137,4 +137,41 @@ namespace LibELF
|
|||
PF_MASKPROC = 0xFF000000,
|
||||
};
|
||||
|
||||
enum ELF_DT
|
||||
{
|
||||
DT_NULL = 0,
|
||||
DT_NEEDED = 1,
|
||||
DT_PLTRELSZ = 2,
|
||||
DT_PLTGOT = 3,
|
||||
DT_HASH = 4,
|
||||
DT_STRTAB = 5,
|
||||
DT_SYMTAB = 6,
|
||||
DT_RELA = 7,
|
||||
DT_RELASZ = 8,
|
||||
DT_RELAENT = 9,
|
||||
DT_STRSZ = 10,
|
||||
DT_SYMENT = 11,
|
||||
DT_INIT = 12,
|
||||
DT_FINI = 13,
|
||||
DT_SONAME = 14,
|
||||
DT_RPATH = 15,
|
||||
DT_SYMBOLIC = 16,
|
||||
DT_REL = 17,
|
||||
DT_RELSZ = 18,
|
||||
DT_RELENT = 19,
|
||||
DT_PLTREL = 20,
|
||||
DT_DEBUG = 21,
|
||||
DT_TEXTREL = 22,
|
||||
DT_JMPREL = 23,
|
||||
DT_BIND_NOW = 24,
|
||||
DT_INIT_ARRAY = 25,
|
||||
DT_FINI_ARRAY = 26,
|
||||
DT_INIT_ARRAYSZ = 27,
|
||||
DT_FINI_ARRAYSZ = 28,
|
||||
DT_LOOS = 0x60000000,
|
||||
DT_HIOS = 0x6FFFFFFF,
|
||||
DT_LOPROC = 0x70000000,
|
||||
DT_HIPROC = 0x7FFFFFFF,
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue