1 #include <lunaix/common.h>
2 #include <lunaix/exebi/elf32.h>
4 #include <lunaix/mm/valloc.h>
5 #include <lunaix/spike.h>
7 #include <klibc/string.h>
10 elf32_read(struct v_file* elf, void* data, size_t off, size_t len)
12 // it is wise to do cached read
13 return pcache_read(elf->inode, data, len, off);
17 elf32_open(struct elf32* elf, const char* path)
19 struct v_dnode* elfdn;
20 struct v_file* elffile;
23 if ((error = vfs_walk_proc(path, &elfdn, NULL, 0))) {
27 if ((error = vfs_open(elfdn, &elffile))) {
31 return elf32_openat(elf, elffile);
35 elf32_openat(struct elf32* elf, const void* elf_vfile)
39 elf->elf_file = elf_vfile;
41 if ((status = elf32_read_ehdr(elf)) < 0) {
46 if ((status = elf32_read_phdr(elf)) < 0) {
55 elf32_close(struct elf32* elf)
62 vfs_close((struct v_file*)elf->elf_file);
65 memset(elf, 0, sizeof(*elf));
71 elf32_static_linked(const struct elf32* elf)
73 for (size_t i = 0; i < elf->eheader.e_phnum; i++) {
74 struct elf32_phdr* phdre = &elf->pheaders[i];
75 if (phdre->p_type == PT_INTERP) {
83 elf32_loadable_memsz(const struct elf32* elf)
85 // XXX: Hmmmm, I am not sure if we need this. This is designed to be handy
86 // if we decided to map the heap region before transfer to loader. As
87 // currently, we push *everything* to user-space loader, thus we modify the
88 // brk syscall to do the initial heap mapping.
91 for (size_t i = 0; i < elf->eheader.e_phnum; i++) {
92 struct elf32_phdr* phdre = &elf->pheaders[i];
93 if (phdre->p_type == PT_LOAD) {
102 elf32_find_loader(const struct elf32* elf, char* path_out, size_t len)
104 int retval = NO_LOADER;
106 assert_msg(len >= sizeof(DEFAULT_LOADER), "path_out: too small");
108 struct v_file* elfile = (struct v_file*)elf->elf_file;
110 for (size_t i = 0; i < elf->eheader.e_phnum; i++) {
111 struct elf32_phdr* phdre = &elf->pheaders[i];
112 if (phdre->p_type == PT_INTERP) {
113 if (len >= phdre->p_filesz) {
118 elf32_read(elfile, path_out, phdre->p_offset, phdre->p_filesz);
132 elf32_read_ehdr(struct elf32* elf)
134 struct v_file* elfile = (struct v_file*)elf->elf_file;
136 return elf32_read(elfile, (void*)&elf->eheader, 0, SIZE_EHDR);
140 elf32_read_phdr(struct elf32* elf)
144 struct v_file* elfile = (struct v_file*)elf->elf_file;
146 size_t entries = elf->eheader.e_phnum;
147 size_t tbl_sz = entries * SIZE_PHDR;
149 struct elf32_phdr* phdrs = valloc(tbl_sz);
155 status = elf32_read(elfile, phdrs, elf->eheader.e_phoff, tbl_sz);
162 elf->pheaders = phdrs;
167 elf32_check_exec(const struct elf32* elf, int type)
169 const struct elf32_ehdr* ehdr = &elf->eheader;
171 return (ehdr->e_entry) && ehdr->e_type == type;
175 elf32_check_arch(const struct elf32* elf)
177 const struct elf32_ehdr* ehdr = &elf->eheader;
179 return *(u32_t*)(ehdr->e_ident) == ELFMAGIC &&
180 ehdr->e_ident[EI_CLASS] == ELFCLASS32 &&
181 ehdr->e_ident[EI_DATA] == ELFDATA2LSB && ehdr->e_machine == EM_386;