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 --- 77 unchanged lines hidden (view full) --- 86 INTREG_ESI, 87 INTREG_EDI, 88 INTREG_EBP 89}; 90 91static const int NumArgumentRegs32 M5_VAR_USED = 92 sizeof(ArgumentReg) / sizeof(const int); 93 |
94X86Process::X86Process(ProcessParams * params, ObjectFile *objFile, 95 SyscallDesc *_syscallDescs, int _numSyscallDescs) 96 : Process(params, objFile), syscallDescs(_syscallDescs), 97 numSyscallDescs(_numSyscallDescs) |
98{ 99 brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize(); 100 brk_point = roundUp(brk_point, PageBytes); 101} 102 |
103X86_64Process::X86_64Process(ProcessParams *params, ObjectFile *objFile, 104 SyscallDesc *_syscallDescs, int _numSyscallDescs) 105 : X86Process(params, objFile, _syscallDescs, _numSyscallDescs) |
106{ 107 108 vsyscallPage.base = 0xffffffffff600000ULL; 109 vsyscallPage.size = PageBytes; 110 vsyscallPage.vtimeOffset = 0x400; 111 vsyscallPage.vgettimeofdayOffset = 0x0; 112 113 // Set up stack. On X86_64 Linux, stack goes from the top of memory --- 11 unchanged lines hidden (view full) --- 125 // MIN_GAP: 128*1024*1024+stack_maxrandom_size() 126 // We do not use any address space layout randomization in gem5 127 // therefore the random fields become zero; the smallest gap space was 128 // chosen but gap could potentially be much larger. 129 mmap_end = (Addr)0x7FFFF7FFF000ULL; 130} 131 132void |
133I386Process::syscall(int64_t callnum, ThreadContext *tc) |
134{ 135 TheISA::PCState pc = tc->pcState(); 136 Addr eip = pc.pc(); 137 if (eip >= vsyscallPage.base && 138 eip < vsyscallPage.base + vsyscallPage.size) { 139 pc.npc(vsyscallPage.base + vsyscallPage.vsysexitOffset); 140 tc->pcState(pc); 141 } |
142 X86Process::syscall(callnum, tc); |
143} 144 145 |
146I386Process::I386Process(ProcessParams *params, ObjectFile *objFile, 147 SyscallDesc *_syscallDescs, int _numSyscallDescs) 148 : X86Process(params, objFile, _syscallDescs, _numSyscallDescs) |
149{ 150 _gdtStart = ULL(0xffffd000); 151 _gdtSize = PageBytes; 152 153 vsyscallPage.base = 0xffffe000ULL; 154 vsyscallPage.size = PageBytes; 155 vsyscallPage.vsyscallOffset = 0x400; 156 vsyscallPage.vsysexitOffset = 0x410; --- 10 unchanged lines hidden (view full) --- 167 // MIN_GAP: 128*1024*1024+stack_maxrandom_size() 168 // We do not use any address space layout randomization in gem5 169 // therefore the random fields become zero; the smallest gap space was 170 // chosen but gap could potentially be much larger. 171 mmap_end = (Addr)0xB7FFF000ULL; 172} 173 174SyscallDesc* |
175X86Process::getDesc(int callnum) |
176{ 177 if (callnum < 0 || callnum >= numSyscallDescs) 178 return NULL; 179 return &syscallDescs[callnum]; 180} 181 182void |
183X86_64Process::initState() |
184{ |
185 X86Process::initState(); |
186 187 argsInit(sizeof(uint64_t), PageBytes); 188 189 // Set up the vsyscall page for this process. 190 allocateMem(vsyscallPage.base, vsyscallPage.size); 191 uint8_t vtimeBlob[] = { 192 0x48,0xc7,0xc0,0xc9,0x00,0x00,0x00, // mov $0xc9,%rax 193 0x0f,0x05, // syscall --- 425 unchanged lines hidden (view full) --- 619 tc->setMiscReg(MISCREG_CR0, cr0); 620 621 tc->setMiscReg(MISCREG_MXCSR, 0x1f80); 622 } 623 } 624} 625 626void |
627I386Process::initState() |
628{ |
629 X86Process::initState(); |
630 631 argsInit(sizeof(uint32_t), PageBytes); 632 633 /* 634 * Set up a GDT for this process. The whole GDT wouldn't really be for 635 * this process, but the only parts we care about are. 636 */ 637 allocateMem(_gdtStart, _gdtSize); --- 101 unchanged lines hidden (view full) --- 739 tc->setMiscReg(MISCREG_CR0, cr0); 740 741 tc->setMiscReg(MISCREG_MXCSR, 0x1f80); 742 } 743} 744 745template<class IntType> 746void |
747X86Process::argsInit(int pageSize, |
748 std::vector<AuxVector<IntType> > extraAuxvs) 749{ 750 int intSize = sizeof(IntType); 751 752 typedef AuxVector<IntType> auxv_t; 753 std::vector<auxv_t> auxv = extraAuxvs; 754 755 string filename; --- 271 unchanged lines hidden (view full) --- 1027 1028 //Align the "stack_min" to a page boundary. 1029 stack_min = roundDown(stack_min, pageSize); 1030 1031// num_processes++; 1032} 1033 1034void |
1035X86_64Process::argsInit(int intSize, int pageSize) |
1036{ 1037 std::vector<AuxVector<uint64_t> > extraAuxvs; 1038 extraAuxvs.push_back(AuxVector<uint64_t>(M5_AT_SYSINFO_EHDR, 1039 vsyscallPage.base)); |
1040 X86Process::argsInit |
1041} 1042 1043void |
1044I386Process::argsInit(int intSize, int pageSize) |
1045{ 1046 std::vector<AuxVector<uint32_t> > extraAuxvs; 1047 //Tell the binary where the vsyscall part of the vsyscall page is. 1048 extraAuxvs.push_back(AuxVector<uint32_t>(M5_AT_SYSINFO, 1049 vsyscallPage.base + vsyscallPage.vsyscallOffset)); 1050 extraAuxvs.push_back(AuxVector<uint32_t>(M5_AT_SYSINFO_EHDR, 1051 vsyscallPage.base)); |
1052 X86Process::argsInit |
1053} 1054 1055void |
1056X86Process::setSyscallReturn(ThreadContext *tc, SyscallReturn retval) |
1057{ 1058 tc->setIntReg(INTREG_RAX, retval.encodedValue()); 1059} 1060 1061X86ISA::IntReg |
1062X86_64Process::getSyscallArg(ThreadContext *tc, int &i) |
1063{ 1064 assert(i < NumArgumentRegs); 1065 return tc->readIntReg(ArgumentReg[i++]); 1066} 1067 1068void |
1069X86_64Process::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val) |
1070{ 1071 assert(i < NumArgumentRegs); 1072 return tc->setIntReg(ArgumentReg[i], val); 1073} 1074 1075X86ISA::IntReg |
1076I386Process::getSyscallArg(ThreadContext *tc, int &i) |
1077{ 1078 assert(i < NumArgumentRegs32); 1079 return tc->readIntReg(ArgumentReg32[i++]); 1080} 1081 1082X86ISA::IntReg |
1083I386Process::getSyscallArg(ThreadContext *tc, int &i, int width) |
1084{ 1085 assert(width == 32 || width == 64); 1086 assert(i < NumArgumentRegs); 1087 uint64_t retVal = tc->readIntReg(ArgumentReg32[i++]) & mask(32); 1088 if (width == 64) 1089 retVal |= ((uint64_t)tc->readIntReg(ArgumentReg[i++]) << 32); 1090 return retVal; 1091} 1092 1093void |
1094I386Process::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val) |
1095{ 1096 assert(i < NumArgumentRegs); 1097 return tc->setIntReg(ArgumentReg[i], val); 1098} |