/** Create a task from the program loader image. * * @param prg Buffer for storing program info. * @param name Name to set for the program's task. * * @return EOK on success or negative error code. * */ int program_create_loader(program_t *prg, char *name) { as_t *as = as_create(0); if (!as) return ENOMEM; void *loader = program_loader; if (!loader) { as_destroy(as); printf("Cannot spawn loader as none was registered\n"); return ENOENT; } prg->loader_status = elf_load((elf_header_t *) program_loader, as, ELD_F_LOADER); if (prg->loader_status != EE_OK) { as_destroy(as); printf("Cannot spawn loader (%s)\n", elf_error(prg->loader_status)); return ENOENT; } return program_create(as, ((elf_header_t *) program_loader)->e_entry, name, prg); }
static Elf64_Shdr* elf64_getshdr_by_ndx(Elf *elf, int idx) { if ((idx < 0) || (idx >= E_HALF(elf->ehdr.e_shnum))) { elf_error("Elf section header out of range"); return NULL; } return (&elf->scns[idx].shdr); }
void* elf_alloc_read(Elf *elf, unsigned int ofs, size_t size) { void *buf = malloc(size); if (buf == NULL) { elf_error("No room for elf_alloc_read"); return (NULL); } elf_read(elf,ofs,buf,size); return (buf); }
Elf* elf_begin(int fd, Elf_Cmd cmd, Elf* usrelf) { Elf* relf; Elf64_Ehdr* ehdrp; /* at the current time we are only dealing with the reading of ELF files */ if (cmd != ELF_C_READ) { elf_error("we can only read ELF files"); return NULL; } if (usrelf) { relf = usrelf; } else { relf = (Elf*)malloc(sizeof(Elf)); if (relf == NULL) { elf_error("No memory for Elf header structure"); return NULL; } } /* initialization of the structure */ memset(relf,0,sizeof(Elf)); relf->fd = fd; relf->allocated = !usrelf; /* expect the file to be open, reset the file pointer */ lseek(fd,0,SEEK_SET); ehdrp = &relf->ehdr; elf_read(relf,0,ehdrp,sizeof(Elf64_Ehdr)); /* verify some information on the hdr */ if (! (IS_ELF(*ehdrp)) ) { elf_error("file is not ELF"); return NULL; } if (ehdrp->e_ident[EI_CLASS] != ELFCLASS64) { elf_error("Elf file is not 64 bit"); return NULL; } if (ehdrp->e_ident[EI_VERSION] != EV_CURRENT) { elf_error("Elf file is not current version"); return NULL; } /* determine if little-endian or big-endian -- must know before we try to access multi-byte fields */ if (ehdrp->e_ident[EI_DATA] == ELFDATA2LSB) { endian_elf = ELFDATA2LSB; DPRINTF((stderr,"Elf is little endian\n")); } else if (ehdrp->e_ident[EI_DATA] == ELFDATA2MSB) { endian_elf = ELFDATA2MSB; DPRINTF((stderr,"Elf is big endian\n")); } else { elf_error("Elf file is neither big nor little endian?"); return NULL; } { /* preparing the section header structures */ int recs = E_HALF(relf->ehdr.e_shnum); int size = recs * sizeof(Elf_Scn); int i; relf->scns = (Elf_Scn*)malloc(size); if (relf->scns == NULL) { elf_error("No memory for Elf section headers"); return NULL; } memset(relf->scns,0,size); DPRINTF((stderr,"Elf has %d sections\n", recs)); for (i=0;i<recs;i++) { long ofs; long n; relf->scns[i].elf = relf; relf->scns[i].idx = i; ofs = E_OFF(relf->ehdr.e_shoff) + i*E_HALF(relf->ehdr.e_shentsize); n = sizeof(Elf64_Shdr); DPRINTF((stderr," section %d is %d bytes at offset %ld\n", i, n, ofs)); elf_read(relf,ofs, &relf->scns[i].shdr,n); } } theElf = relf; return (relf); }