int InterpretedPrim_Cache::number_of_parameters() const { int result = name()->number_of_arguments() + (has_receiver() ? 1 : 0) - (has_failure_code() ? 1 : 0); assert(pdesc() == NULL || pdesc()->number_of_parameters() == result, "checking result"); return result; }
static void mparse_readfd_r(struct mparse *curp, int fd, const char *file, int re) { const char *svfile; if (-1 == fd) if (-1 == (fd = open(file, O_RDONLY, 0))) { perror(file); curp->file_status = MANDOCLEVEL_SYSERR; return; } svfile = curp->file; curp->file = file; pdesc(curp, file, fd); if (0 == re && MANDOCLEVEL_FATAL > curp->file_status) mparse_end(curp); if (STDIN_FILENO != fd && -1 == close(fd)) perror(file); curp->file = svfile; }
int PrimitiveCallNode::number_of_parameters() const { int result = name()->number_of_arguments() + (has_receiver() ? 1 : 0) - (failure_code() ? 1 : 0); assert(_pdesc == NULL || pdesc()->number_of_parameters() == result, "checking result"); return result; }
static void pdesc(char *desc) { char *ptr,*nptr; ptr=desc; if ((int)strlen(ptr) < 70) fprintf(stderr,"\t%s\n",ptr); else { for(nptr=ptr+70; (nptr != ptr) && (!isspace(*nptr)); nptr--) ; if (nptr == ptr) fprintf(stderr,"\t%s\n",ptr); else { *nptr='\0'; nptr++; fprintf(stderr,"\t%s\n",ptr); pdesc(nptr); } } }
VAddr _loadElfObject(ThreadContext *context, FileSys::SeekableDescription *fdesc, VAddr addr, bool isInterpreter){ typedef typename ElfDefs<mode>::Elf_Ehdr Elf_Ehdr; typedef typename ElfDefs<mode>::Elf_Phdr Elf_Phdr; // Set if this is a dynamically linked executable and we found the interpreter bool hasInterpreter=false; // Read in the ELF header Elf_Ehdr ehdr; ssize_t ehdrSiz=fdesc->pread(&ehdr,sizeof(Elf_Ehdr),0); cvtEndianEhdr<mode>(ehdr); I(ehdrSiz==sizeof(Elf_Ehdr)); // Clear all the registers (this is actually needed for correct operation) context->clearRegs(); // Set the ExecMode of the processor to match executable // TODO: Do this only for executable, for interpreter check if it matches if(isInterpreter&&(context->getMode()!=mode)) fail("loadElfObject: executable with mode %x has interpreter with mode %x\n", context->getMode(),mode); context->setMode(mode); // Read in program (segment) headers Elf_Phdr phdrs[ehdr.e_phnum]; ssize_t phdrsSiz=fdesc->pread(phdrs,sizeof(Elf_Phdr)*ehdr.e_phnum,ehdr.e_phoff); I(phdrsSiz==(ssize_t)(sizeof(Elf_Phdr)*ehdr.e_phnum)); I(phdrsSiz==(ssize_t)(sizeof(phdrs))); for(size_t seg=0;seg<ehdr.e_phnum;seg++) cvtEndianPhdr<mode>(phdrs[seg]); // Iterate over all segments to load interpreter and find top and bottom of address range VAddr loReqAddr=0; VAddr hiReqAddr=0; for(size_t seg=0;seg<ehdr.e_phnum;seg++){ switch(phdrs[seg].p_type){ case PT_INTERP: { char interpName[phdrs[seg].p_filesz]; ssize_t interpNameSiz=fdesc->pread(interpName,phdrs[seg].p_filesz,phdrs[seg].p_offset); I(interpNameSiz==ssize_t(phdrs[seg].p_filesz)); const std::string exeLinkName(context->getFileSys()->toHost(interpName)); const std::string exeRealName(FileSys::Node::resolve(exeLinkName)); if(exeRealName.empty()) fail("loadElfObject: Link loop when executable %s\n",exeLinkName.c_str()); FileSys::Node *node=FileSys::Node::lookup(exeRealName); if(!node) fail("loadElfObject: Executable %s does not exist\n",exeLinkName.c_str()); FileSys::FileNode *fnode=dynamic_cast<FileSys::FileNode *>(node); if(!fnode) fail("loadElfObject: Executable %s is not a regular file\n",exeLinkName.c_str()); FileSys::FileDescription *fdesc=new FileSys::FileDescription(fnode,O_RDONLY); FileSys::Description::pointer pdesc(fdesc); addr=_loadElfObject<mode>(context,fdesc,addr,true); hasInterpreter=true; } break; case PT_LOAD: if(loReqAddr==hiReqAddr){ loReqAddr=phdrs[seg].p_vaddr; hiReqAddr=phdrs[seg].p_vaddr+phdrs[seg].p_memsz; } if(phdrs[seg].p_vaddr<loReqAddr) loReqAddr=phdrs[seg].p_vaddr; if(phdrs[seg].p_vaddr+phdrs[seg].p_memsz>hiReqAddr) hiReqAddr=phdrs[seg].p_vaddr+phdrs[seg].p_memsz; break; } } VAddr loadAddr=addr+context->getAddressSpace()->getPageSize()-1; loadAddr=loadAddr-(loadAddr%context->getAddressSpace()->getPageSize()); switch(ehdr.e_type){ case ET_EXEC: loadAddr=loReqAddr; break; case ET_DYN: break; } I(context->getAddressSpace()->isNoSegment(loadAddr,hiReqAddr-loReqAddr)); for(size_t seg=0;seg<ehdr.e_phnum;seg++){ if(phdrs[seg].p_type!=PT_LOAD) continue; VAddr segFilAddr=loadAddr+(phdrs[seg].p_vaddr-loReqAddr); size_t segFilLen=phdrs[seg].p_filesz; VAddr segMapAddr=context->getAddressSpace()->pageAlignDown(segFilAddr); size_t segMapLen=context->getAddressSpace()->pageAlignUp((segFilAddr-segMapAddr)+phdrs[seg].p_memsz); // Map segment into address space if(!context->getAddressSpace()->isNoSegment(segMapAddr,segMapLen)) fail("Segment overlap is loadElfObject\n"); context->getAddressSpace()->newSegment(segMapAddr,segMapLen,false,true,false,false,fdesc, context->getAddressSpace()->pageAlignDown(phdrs[seg].p_offset)); context->writeMemWithByte(segMapAddr,segFilAddr-segMapAddr,0); context->writeMemWithByte(segFilAddr+segFilLen,(segMapAddr+segMapLen)-(segFilAddr+segFilLen),0); context->getAddressSpace()->protectSegment(segMapAddr,segMapLen, phdrs[seg].p_flags&PF_R, phdrs[seg].p_flags&PF_W, phdrs[seg].p_flags&PF_X); _mapFuncNames<mode>(context,fdesc,segFilAddr,segFilLen,phdrs[seg].p_offset); if((!isInterpreter)&&(phdrs[seg].p_offset<=ehdr.e_phoff)&& (phdrs[seg].p_offset+phdrs[seg].p_filesz>=ehdr.e_phoff+ehdr.e_phnum*sizeof(Elf_Phdr))){ context->getAddressSpace()->addFuncName(segFilAddr+ehdr.e_phoff-phdrs[seg].p_offset,"PrgHdrAddr",""); context->getAddressSpace()->addFuncName(sizeof(Elf_Phdr),"PrgHdrEnt" ,""); context->getAddressSpace()->addFuncName(ehdr.e_phnum,"PrgHdrNum",""); } } context->getAddressSpace()->setBrkBase(loadAddr+(hiReqAddr-loReqAddr)); VAddr entryAddr=loadAddr+(ehdr.e_entry-loReqAddr); // This is the entry point of the program (not the interpreter) if(!isInterpreter) context->getAddressSpace()->addFuncName(entryAddr,"UserEntry",""); // If there is an interpreter, we enter there, otherwise we enter the program if(isInterpreter||!hasInterpreter) context->setIAddr(entryAddr); return loadAddr+(hiReqAddr-loReqAddr); }
void emulInit(int32_t argc, char **argv, char **envp){ FileSys::Node::insert("/dev/null",new FileSys::NullNode()); FileSys::Node::insert("/dev/tty",0); FileSys::Description *inDescription=0; FileSys::Description *outDescription=0; FileSys::Description *errDescription=0; extern char *optarg; int32_t opt; while((opt=getopt(argc, argv, "+hi:o:e:"))!=-1){ switch(opt){ case 'i': inDescription=FileSys::Description::open(optarg,O_RDONLY,S_IRUSR); if(!inDescription) fail("Could not open `%s' as simulated stdin file\n",optarg); break; case 'o': outDescription=FileSys::Description::open(optarg,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR); if(!outDescription) fail("Could not open `%s' as simulated stdout file\n",optarg); break; case 'e': errDescription=FileSys::Description::open(optarg,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR); if(!errDescription) fail("Could not open `%s' as simulated stderr file %s\n",optarg); break; case 'h': default: fail("\n" "Usage: %s [EmulOpts] [-- SimOpts] AppExec [AppOpts]\n" " EmulOpts:\n" " [-i FName] Use file FName as stdin for AppExec\n" " [-o FName] Use file FName as stdout for AppExec\n" " [-e FName] Use file FName as stderr for AppExec\n", argv[0]); } } if(!inDescription){ inDescription=FileSys::TtyDescription::wrap(STDIN_FILENO); if(!inDescription) fail("Could not wrap stdin\n"); } if(!outDescription){ outDescription=FileSys::TtyDescription::wrap(STDOUT_FILENO); if(!outDescription) fail("Could not wrap stdout\n"); } if(!errDescription){ errDescription=FileSys::TtyDescription::wrap(STDERR_FILENO); if(!errDescription) fail("Could not wrap stderr\n"); } int32_t appArgc=argc-optind; char **appArgv=&(argv[optind]); char **appEnvp=envp; // Count environment variables int32_t appEnvc=0; while(appEnvp[appEnvc]) appEnvc++; FileSys::NameSpace::pointer nameSpace(new FileSys::NameSpace(SescConf->getCharPtr("FileSys","mount"))); char hostCwd[PATH_MAX]; if(getcwd(hostCwd,PATH_MAX)==0) fail("emulInit: Failed to get host current directory (getcwd)\n"); const string targetCwd(nameSpace->toTarget(nameSpace->normalize("/",hostCwd))); FileSys::FileSys::pointer fileSys(new FileSys::FileSys(nameSpace,targetCwd)); const string exeLinkName(fileSys->toHost(appArgv[0])); const string exeRealName(FileSys::Node::resolve(exeLinkName)); if(exeRealName.empty()) fail("emulInit: Link loop when executable %s\n",exeLinkName.c_str()); FileSys::Node *node=FileSys::Node::lookup(exeRealName); if(!node) fail("emulInit: Executable %s does not exist\n",exeLinkName.c_str()); FileSys::FileNode *fnode=dynamic_cast<FileSys::FileNode *>(node); if(!fnode) fail("emulInit: Executable %s is not a regular file\n",exeLinkName.c_str()); FileSys::FileDescription *fdesc=new FileSys::FileDescription(fnode,O_RDONLY); FileSys::Description::pointer pdesc(fdesc); ThreadContext *mainThread=new ThreadContext(fileSys); // TODO: Use ELF_ET_DYN_BASE instead of a constant here loadElfObject(mainThread,fdesc,0x200000); mainThread->getSystem()->initSystem(mainThread); mainThread->getSystem()->createStack(mainThread); mainThread->getSystem()->setProgArgs(mainThread,appArgc,appArgv,appEnvc,appEnvp); FileSys::OpenFiles *openFiles=mainThread->getOpenFiles(); openFiles->openDescriptor(STDIN_FILENO,inDescription); openFiles->openDescriptor(STDOUT_FILENO,outDescription); openFiles->openDescriptor(STDERR_FILENO,errDescription); }
QString dllForExport::getDescription() { if(pdesc!=0)return pdesc(); }