1/* 2 * Copyright (c) 2014 Advanced Micro Devices, Inc. 3 * Copyright (c) 2007 The Hewlett-Packard Development Company 4 * All rights reserved. 5 * 6 * The license below extends only to copyright in the software and shall 7 * not be construed as granting a license to any other intellectual 8 * property including but not limited to intellectual property relating --- 86 unchanged lines hidden (view full) --- 95static const int NumArgumentRegs32 M5_VAR_USED = 96 sizeof(ArgumentReg) / sizeof(const int); 97 98X86Process::X86Process(ProcessParams * params, ObjectFile *objFile, 99 SyscallDesc *_syscallDescs, int _numSyscallDescs) 100 : Process(params, objFile), syscallDescs(_syscallDescs), 101 numSyscallDescs(_numSyscallDescs) 102{ |
103 memState->brkPoint = objFile->dataBase() + objFile->dataSize() 104 + objFile->bssSize(); 105 memState->brkPoint = roundUp(memState->brkPoint, PageBytes); |
106} 107 |
108void X86Process::clone(ThreadContext *old_tc, ThreadContext *new_tc, 109 Process *p, TheISA::IntReg flags) 110{ 111 Process::clone(old_tc, new_tc, p, flags); 112 X86Process *process = (X86Process*)p; 113 *process = *this; 114} 115 |
116X86_64Process::X86_64Process(ProcessParams *params, ObjectFile *objFile, 117 SyscallDesc *_syscallDescs, int _numSyscallDescs) 118 : X86Process(params, objFile, _syscallDescs, _numSyscallDescs) 119{ 120 121 vsyscallPage.base = 0xffffffffff600000ULL; 122 vsyscallPage.size = PageBytes; 123 vsyscallPage.vtimeOffset = 0x400; 124 vsyscallPage.vgettimeofdayOffset = 0x0; 125 126 // Set up stack. On X86_64 Linux, stack goes from the top of memory 127 // downward, less the hole for the kernel address space plus one page 128 // for undertermined purposes. |
129 memState->stackBase = (Addr)0x7FFFFFFFF000ULL; |
130 131 // Set pointer for next thread stack. Reserve 8M for main stack. |
132 memState->nextThreadStackBase = memState->stackBase - (8 * 1024 * 1024); |
133 134 // "mmap_base" is a function which defines where mmap region starts in 135 // the process address space. 136 // mmap_base: PAGE_ALIGN(TASK_SIZE-MIN_GAP-mmap_rnd()) 137 // TASK_SIZE: (1<<47)-PAGE_SIZE 138 // MIN_GAP: 128*1024*1024+stack_maxrandom_size() 139 // We do not use any address space layout randomization in gem5 140 // therefore the random fields become zero; the smallest gap space was 141 // chosen but gap could potentially be much larger. |
142 memState->mmapEnd = (Addr)0x7FFFF7FFF000ULL; |
143} 144 145void 146I386Process::syscall(int64_t callnum, ThreadContext *tc, Fault *fault) 147{ 148 TheISA::PCState pc = tc->pcState(); 149 Addr eip = pc.pc(); 150 if (eip >= vsyscallPage.base && --- 12 unchanged lines hidden (view full) --- 163 _gdtStart = ULL(0xffffd000); 164 _gdtSize = PageBytes; 165 166 vsyscallPage.base = 0xffffe000ULL; 167 vsyscallPage.size = PageBytes; 168 vsyscallPage.vsyscallOffset = 0x400; 169 vsyscallPage.vsysexitOffset = 0x410; 170 |
171 memState->stackBase = _gdtStart; |
172 173 // Set pointer for next thread stack. Reserve 8M for main stack. |
174 memState->nextThreadStackBase = memState->stackBase - (8 * 1024 * 1024); |
175 176 // "mmap_base" is a function which defines where mmap region starts in 177 // the process address space. 178 // mmap_base: PAGE_ALIGN(TASK_SIZE-MIN_GAP-mmap_rnd()) 179 // TASK_SIZE: 0xC0000000 180 // MIN_GAP: 128*1024*1024+stack_maxrandom_size() 181 // We do not use any address space layout randomization in gem5 182 // therefore the random fields become zero; the smallest gap space was 183 // chosen but gap could potentially be much larger. |
184 memState->mmapEnd = (Addr)0xB7FFF000ULL; |
185} 186 187SyscallDesc* 188X86Process::getDesc(int callnum) 189{ 190 if (callnum < 0 || callnum >= numSyscallDescs) 191 return NULL; 192 return &syscallDescs[callnum]; --- 757 unchanged lines hidden (view full) --- 950 int aux_padding = aligned_partial_size - partial_size; 951 952 int space_needed = 953 info_block_size + 954 aux_data_size + 955 aux_padding + 956 frame_size; 957 |
958 memState->stackMin = memState->stackBase - space_needed; 959 memState->stackMin = roundDown(memState->stackMin, align); 960 memState->stackSize = roundUp(memState->stackBase - memState->stackMin, 961 pageSize); |
962 963 // map memory |
964 Addr stack_end = roundDown(memState->stackBase - memState->stackSize, 965 pageSize); |
966 |
967 DPRINTF(Stack, "Mapping the stack: 0x%x %dB\n", 968 stack_end, memState->stackSize); 969 allocateMem(stack_end, memState->stackSize); |
970 971 // map out initial stack contents |
972 IntType sentry_base = memState->stackBase - sentry_size; |
973 IntType file_name_base = sentry_base - file_name_size; 974 IntType env_data_base = file_name_base - env_data_size; 975 IntType arg_data_base = env_data_base - arg_data_size; 976 IntType aux_data_base = arg_data_base - info_block_padding - aux_data_size; 977 IntType auxv_array_base = aux_data_base - aux_array_size - aux_padding; 978 IntType envp_array_base = auxv_array_base - envp_array_size; 979 IntType argv_array_base = envp_array_base - argv_array_size; 980 IntType argc_base = argv_array_base - argc_size; 981 982 DPRINTF(Stack, "The addresses of items on the initial stack:\n"); 983 DPRINTF(Stack, "0x%x - file name\n", file_name_base); 984 DPRINTF(Stack, "0x%x - env data\n", env_data_base); 985 DPRINTF(Stack, "0x%x - arg data\n", arg_data_base); 986 DPRINTF(Stack, "0x%x - aux data\n", aux_data_base); 987 DPRINTF(Stack, "0x%x - auxv array\n", auxv_array_base); 988 DPRINTF(Stack, "0x%x - envp array\n", envp_array_base); 989 DPRINTF(Stack, "0x%x - argv array\n", argv_array_base); 990 DPRINTF(Stack, "0x%x - argc \n", argc_base); |
991 DPRINTF(Stack, "0x%x - stack min\n", memState->stackMin); |
992 993 // write contents to stack 994 995 // figure out argc 996 IntType argc = argv.size(); 997 IntType guestArgc = X86ISA::htog(argc); 998 999 //Write out the sentry void * --- 30 unchanged lines hidden (view full) --- 1030 1031 copyStringArray(envp, envp_array_base, env_data_base, initVirtMem); 1032 copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem); 1033 1034 initVirtMem.writeBlob(argc_base, (uint8_t*)&guestArgc, intSize); 1035 1036 ThreadContext *tc = system->getThreadContext(contextIds[0]); 1037 //Set the stack pointer register |
1038 tc->setIntReg(StackPointerReg, memState->stackMin); |
1039 1040 // There doesn't need to be any segment base added in since we're dealing 1041 // with the flat segmentation model. 1042 tc->pcState(getStartPC()); 1043 1044 //Align the "stack_min" to a page boundary. |
1045 memState->stackMin = roundDown(memState->stackMin, pageSize); |
1046} 1047 1048void 1049X86_64Process::argsInit(int pageSize) 1050{ 1051 std::vector<AuxVector<uint64_t> > extraAuxvs; 1052 extraAuxvs.push_back(AuxVector<uint64_t>(M5_AT_SYSINFO_EHDR, 1053 vsyscallPage.base)); --- 27 unchanged lines hidden (view full) --- 1081 1082void 1083X86_64Process::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val) 1084{ 1085 assert(i < NumArgumentRegs); 1086 return tc->setIntReg(ArgumentReg[i], val); 1087} 1088 |
1089void 1090X86_64Process::clone(ThreadContext *old_tc, ThreadContext *new_tc, 1091 Process *p, TheISA::IntReg flags) 1092{ 1093 X86Process::clone(old_tc, new_tc, p, flags); 1094 ((X86_64Process*)p)->vsyscallPage = vsyscallPage; 1095} 1096 |
1097X86ISA::IntReg 1098I386Process::getSyscallArg(ThreadContext *tc, int &i) 1099{ 1100 assert(i < NumArgumentRegs32); 1101 return tc->readIntReg(ArgumentReg32[i++]); 1102} 1103 1104X86ISA::IntReg --- 8 unchanged lines hidden (view full) --- 1113} 1114 1115void 1116I386Process::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val) 1117{ 1118 assert(i < NumArgumentRegs); 1119 return tc->setIntReg(ArgumentReg[i], val); 1120} |
1121 1122void 1123I386Process::clone(ThreadContext *old_tc, ThreadContext *new_tc, 1124 Process *p, TheISA::IntReg flags) 1125{ 1126 X86Process::clone(old_tc, new_tc, p, flags); 1127 ((I386Process*)p)->vsyscallPage = vsyscallPage; 1128} |