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 *)&regVal, 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 *)&regVal, 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 + -
显示快捷键?