1 #include <lunaix/exebi/elf.h>
3 #include <lunaix/mm/valloc.h>
4 #include <lunaix/spike.h>
6 #include <klibc/string.h>
9 elf_read(struct v_file* elf, void* data, size_t off, size_t len)
11 // it is wise to do cached read
12 return pcache_read(elf->inode, data, len, off);
16 elf_do_open(struct elf* elf, struct v_file* elf_file)
20 elf->elf_file = elf_file;
22 if ((status = elf_read_ehdr(elf)) < 0) {
27 if (!elf_check_arch(elf)) {
31 if ((status = elf_read_phdr(elf)) < 0) {
40 elf_open(struct elf* elf, const char* path)
42 struct v_dnode* elfdn;
43 struct v_file* elffile;
46 if ((error = vfs_walk_proc(path, &elfdn, NULL, 0))) {
50 if ((error = vfs_open(elfdn, &elffile))) {
54 return elf_do_open(elf, elffile);
58 elf_openat(struct elf* elf, void* elf_vfile)
60 // so the ref count kept in sync
61 vfs_ref_file(elf_vfile);
62 return elf_do_open(elf, elf_vfile);
66 elf_close(struct elf* elf)
73 vfs_close((struct v_file*)elf->elf_file);
76 memset(elf, 0, sizeof(*elf));
82 elf_static_linked(const struct elf* elf)
84 for (size_t i = 0; i < elf->eheader.e_phnum; i++) {
85 struct elf_phdr* phdre = &elf->pheaders[i];
86 if (phdre->p_type == PT_INTERP) {
94 elf_loadable_memsz(const struct elf* elf)
96 // XXX: Hmmmm, I am not sure if we need this. This is designed to be handy
97 // if we decided to map the heap region before transfer to loader. As
98 // currently, we push *everything* to user-space loader, thus we modify the
99 // brk syscall to do the initial heap mapping.
102 for (size_t i = 0; i < elf->eheader.e_phnum; i++) {
103 struct elf_phdr* phdre = &elf->pheaders[i];
104 if (phdre->p_type == PT_LOAD) {
105 sz += phdre->p_memsz;
113 elf_find_loader(const struct elf* elf, char* path_out, size_t len)
115 int retval = NO_LOADER;
117 assert_msg(len >= sizeof(DEFAULT_LOADER), "path_out: too small");
119 struct v_file* elfile = (struct v_file*)elf->elf_file;
121 for (size_t i = 0; i < elf->eheader.e_phnum; i++) {
122 struct elf_phdr* phdre = &elf->pheaders[i];
123 if (phdre->p_type == PT_INTERP) {
124 if (len >= phdre->p_filesz) {
129 elf_read(elfile, path_out, phdre->p_offset, phdre->p_filesz);
143 elf_read_ehdr(struct elf* elf)
145 struct v_file* elfile = (struct v_file*)elf->elf_file;
147 return elf_read(elfile, (void*)&elf->eheader, 0, SIZE_EHDR);
151 elf_read_phdr(struct elf* elf)
155 struct v_file* elfile = (struct v_file*)elf->elf_file;
157 size_t entries = elf->eheader.e_phnum;
158 size_t tbl_sz = entries * SIZE_PHDR;
160 struct elf_phdr* phdrs = valloc(tbl_sz);
166 status = elf_read(elfile, phdrs, elf->eheader.e_phoff, tbl_sz);
173 elf->pheaders = phdrs;
178 elf_check_exec(const struct elf* elf, int type)
180 const struct elf_ehdr* ehdr = &elf->eheader;
182 return (ehdr->e_entry) && ehdr->e_type == type;
186 elf_check_arch(const struct elf* elf)
188 const struct elf_ehdr* ehdr = &elf->eheader;
190 return *(u32_t*)(ehdr->e_ident) == ELFMAGIC_LE;