process.cc
来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· CC 代码 · 共 508 行 · 第 1/2 页
CC
508 行
auxv.push_back(auxv_t(M5_AT_UID, uid())); auxv.push_back(auxv_t(M5_AT_EUID, euid())); auxv.push_back(auxv_t(M5_AT_GID, gid())); auxv.push_back(auxv_t(M5_AT_EGID, egid())); //Whether to enable "secure mode" in the executable auxv.push_back(auxv_t(M5_AT_SECURE, 0)); } //Figure out how big the initial stack needs to be // The unaccounted for 8 byte 0 at the top of the stack int sentry_size = 8; //This is the name of the file which is present on the initial stack //It's purpose is to let the user space linker examine the original file. int file_name_size = filename.size() + 1; int env_data_size = 0; for (int i = 0; i < envp.size(); ++i) { env_data_size += envp[i].size() + 1; } int arg_data_size = 0; for (int i = 0; i < argv.size(); ++i) { arg_data_size += argv[i].size() + 1; } //The info_block. int base_info_block_size = sentry_size + file_name_size + env_data_size + arg_data_size; int info_block_size = roundUp(base_info_block_size, align); int info_block_padding = info_block_size - base_info_block_size; //Each auxilliary vector is two words int aux_array_size = intSize * 2 * (auxv.size() + 1); int envp_array_size = intSize * (envp.size() + 1); int argv_array_size = intSize * (argv.size() + 1); int argc_size = intSize; int window_save_size = intSize * 16; //Figure out the size of the contents of the actual initial frame int frame_size = aux_array_size + envp_array_size + argv_array_size + argc_size + window_save_size; //There needs to be padding after the auxiliary vector data so that the //very bottom of the stack is aligned properly. int aligned_partial_size = roundUp(frame_size, align); int aux_padding = aligned_partial_size - frame_size; int space_needed = info_block_size + aux_padding + frame_size; stack_min = stack_base - space_needed; stack_min = roundDown(stack_min, align); stack_size = stack_base - stack_min; // Allocate space for the stack pTable->allocate(roundDown(stack_min, pageSize), roundUp(stack_size, pageSize)); // map out initial stack contents IntType sentry_base = stack_base - sentry_size; IntType file_name_base = sentry_base - file_name_size; IntType env_data_base = file_name_base - env_data_size; IntType arg_data_base = env_data_base - arg_data_size; IntType auxv_array_base = arg_data_base - info_block_padding - aux_array_size - aux_padding; IntType envp_array_base = auxv_array_base - envp_array_size; IntType argv_array_base = envp_array_base - argv_array_size; IntType argc_base = argv_array_base - argc_size;#if TRACING_ON IntType window_save_base = argc_base - window_save_size;#endif DPRINTF(Sparc, "The addresses of items on the initial stack:\n"); DPRINTF(Sparc, "%#x - sentry NULL\n", sentry_base); DPRINTF(Sparc, "filename = %s\n", filename); DPRINTF(Sparc, "%#x - file name\n", file_name_base); DPRINTF(Sparc, "%#x - env data\n", env_data_base); DPRINTF(Sparc, "%#x - arg data\n", arg_data_base); DPRINTF(Sparc, "%#x - auxv array\n", auxv_array_base); DPRINTF(Sparc, "%#x - envp array\n", envp_array_base); DPRINTF(Sparc, "%#x - argv array\n", argv_array_base); DPRINTF(Sparc, "%#x - argc \n", argc_base); DPRINTF(Sparc, "%#x - window save\n", window_save_base); DPRINTF(Sparc, "%#x - stack min\n", stack_min); assert(window_save_base == stack_min); // write contents to stack // figure out argc IntType argc = argv.size(); IntType guestArgc = TheISA::htog(argc); //Write out the sentry void * uint64_t sentry_NULL = 0; initVirtMem->writeBlob(sentry_base, (uint8_t*)&sentry_NULL, sentry_size); //Write the file name initVirtMem->writeString(file_name_base, filename.c_str()); //Copy the aux stuff for(int x = 0; x < auxv.size(); x++) { initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize, (uint8_t*)&(auxv[x].a_type), intSize); initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize, (uint8_t*)&(auxv[x].a_val), intSize); } //Write out the terminating zeroed auxilliary vector const IntType zero = 0; initVirtMem->writeBlob(auxv_array_base + intSize * 2 * auxv.size(), (uint8_t*)&zero, intSize); initVirtMem->writeBlob(auxv_array_base + intSize * (2 * auxv.size() + 1), (uint8_t*)&zero, intSize); copyStringArray(envp, envp_array_base, env_data_base, initVirtMem); copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem); initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize); //Set up space for the trap handlers into the processes address space. //Since the stack grows down and there is reserved address space abov //it, we can put stuff above it and stay out of the way. fillStart = stack_base; spillStart = fillStart + sizeof(MachInst) * numFillInsts; //Set up the thread context to start running the process //assert(NumArgumentRegs >= 2); //threadContexts[0]->setIntReg(ArgumentReg[0], argc); //threadContexts[0]->setIntReg(ArgumentReg[1], argv_array_base); threadContexts[0]->setIntReg(StackPointerReg, stack_min - StackBias); // %g1 is a pointer to a function that should be run at exit. Since we // don't have anything like that, it should be set to 0. threadContexts[0]->setIntReg(1, 0); Addr prog_entry = objFile->entryPoint(); threadContexts[0]->setPC(prog_entry); threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst)); threadContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst))); //Align the "stack_min" to a page boundary. stack_min = roundDown(stack_min, pageSize);// num_processes++;}voidSparc64LiveProcess::argsInit(int intSize, int pageSize){ SparcLiveProcess::argsInit<uint64_t>(pageSize); // Stuff the trap handlers into the process address space initVirtMem->writeBlob(fillStart, (uint8_t*)fillHandler64, sizeof(MachInst) * numFillInsts); initVirtMem->writeBlob(spillStart, (uint8_t*)spillHandler64, sizeof(MachInst) * numSpillInsts);}voidSparc32LiveProcess::argsInit(int intSize, int pageSize){ SparcLiveProcess::argsInit<uint32_t>(pageSize); // Stuff the trap handlers into the process address space initVirtMem->writeBlob(fillStart, (uint8_t*)fillHandler32, sizeof(MachInst) * numFillInsts); initVirtMem->writeBlob(spillStart, (uint8_t*)spillHandler32, sizeof(MachInst) * numSpillInsts);}void Sparc32LiveProcess::flushWindows(ThreadContext *tc){ IntReg Cansave = tc->readIntReg(NumIntArchRegs + 3); IntReg Canrestore = tc->readIntReg(NumIntArchRegs + 4); IntReg Otherwin = tc->readIntReg(NumIntArchRegs + 6); MiscReg CWP = tc->readMiscReg(MISCREG_CWP); MiscReg origCWP = CWP; CWP = (CWP + Cansave + 2) % NWindows; while(NWindows - 2 - Cansave != 0) { if (Otherwin) { panic("Otherwin non-zero.\n"); } else { tc->setMiscReg(MISCREG_CWP, CWP); //Do the stores IntReg sp = tc->readIntReg(StackPointerReg); for (int index = 16; index < 32; index++) { uint32_t regVal = tc->readIntReg(index); regVal = htog(regVal); if (!tc->getMemPort()->tryWriteBlob( sp + (index - 16) * 4, (uint8_t *)®Val, 4)) { warn("Failed to save register to the stack when " "flushing windows.\n"); } } Canrestore--; Cansave++; CWP = (CWP + 1) % NWindows; } } tc->setIntReg(NumIntArchRegs + 3, Cansave); tc->setIntReg(NumIntArchRegs + 4, Canrestore); tc->setMiscReg(MISCREG_CWP, origCWP);}void Sparc64LiveProcess::flushWindows(ThreadContext *tc){ IntReg Cansave = tc->readIntReg(NumIntArchRegs + 3); IntReg Canrestore = tc->readIntReg(NumIntArchRegs + 4); IntReg Otherwin = tc->readIntReg(NumIntArchRegs + 6); MiscReg CWP = tc->readMiscReg(MISCREG_CWP); MiscReg origCWP = CWP; CWP = (CWP + Cansave + 2) % NWindows; while(NWindows - 2 - Cansave != 0) { if (Otherwin) { panic("Otherwin non-zero.\n"); } else { tc->setMiscReg(MISCREG_CWP, CWP); //Do the stores IntReg sp = tc->readIntReg(StackPointerReg); for (int index = 16; index < 32; index++) { IntReg regVal = tc->readIntReg(index); regVal = htog(regVal); if (!tc->getMemPort()->tryWriteBlob( sp + 2047 + (index - 16) * 8, (uint8_t *)®Val, 8)) { warn("Failed to save register to the stack when " "flushing windows.\n"); } } Canrestore--; Cansave++; CWP = (CWP + 1) % NWindows; } } tc->setIntReg(NumIntArchRegs + 3, Cansave); tc->setIntReg(NumIntArchRegs + 4, Canrestore); tc->setMiscReg(MISCREG_CWP, origCWP);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?