process.cc (11800:54436a1784dc) process.cc (11851:824055fe6b30)
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
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
94X86LiveProcess::X86LiveProcess(LiveProcessParams * params, ObjectFile *objFile,
95 SyscallDesc *_syscallDescs, int _numSyscallDescs) :
96 LiveProcess(params, objFile), syscallDescs(_syscallDescs),
97 numSyscallDescs(_numSyscallDescs)
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
98{
99 brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
100 brk_point = roundUp(brk_point, PageBytes);
101}
102
103X86_64LiveProcess::X86_64LiveProcess(LiveProcessParams *params,
104 ObjectFile *objFile, SyscallDesc *_syscallDescs,
105 int _numSyscallDescs) :
106 X86LiveProcess(params, objFile, _syscallDescs, _numSyscallDescs)
103X86_64Process::X86_64Process(ProcessParams *params, ObjectFile *objFile,
104 SyscallDesc *_syscallDescs, int _numSyscallDescs)
105 : X86Process(params, objFile, _syscallDescs, _numSyscallDescs)
107{
108
109 vsyscallPage.base = 0xffffffffff600000ULL;
110 vsyscallPage.size = PageBytes;
111 vsyscallPage.vtimeOffset = 0x400;
112 vsyscallPage.vgettimeofdayOffset = 0x0;
113
114 // Set up stack. On X86_64 Linux, stack goes from the top of memory

--- 11 unchanged lines hidden (view full) ---

126 // MIN_GAP: 128*1024*1024+stack_maxrandom_size()
127 // We do not use any address space layout randomization in gem5
128 // therefore the random fields become zero; the smallest gap space was
129 // chosen but gap could potentially be much larger.
130 mmap_end = (Addr)0x7FFFF7FFF000ULL;
131}
132
133void
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
134I386LiveProcess::syscall(int64_t callnum, ThreadContext *tc)
133I386Process::syscall(int64_t callnum, ThreadContext *tc)
135{
136 TheISA::PCState pc = tc->pcState();
137 Addr eip = pc.pc();
138 if (eip >= vsyscallPage.base &&
139 eip < vsyscallPage.base + vsyscallPage.size) {
140 pc.npc(vsyscallPage.base + vsyscallPage.vsysexitOffset);
141 tc->pcState(pc);
142 }
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 }
143 X86LiveProcess::syscall(callnum, tc);
142 X86Process::syscall(callnum, tc);
144}
145
146
143}
144
145
147I386LiveProcess::I386LiveProcess(LiveProcessParams *params,
148 ObjectFile *objFile, SyscallDesc *_syscallDescs,
149 int _numSyscallDescs) :
150 X86LiveProcess(params, objFile, _syscallDescs, _numSyscallDescs)
146I386Process::I386Process(ProcessParams *params, ObjectFile *objFile,
147 SyscallDesc *_syscallDescs, int _numSyscallDescs)
148 : X86Process(params, objFile, _syscallDescs, _numSyscallDescs)
151{
152 _gdtStart = ULL(0xffffd000);
153 _gdtSize = PageBytes;
154
155 vsyscallPage.base = 0xffffe000ULL;
156 vsyscallPage.size = PageBytes;
157 vsyscallPage.vsyscallOffset = 0x400;
158 vsyscallPage.vsysexitOffset = 0x410;

--- 10 unchanged lines hidden (view full) ---

169 // MIN_GAP: 128*1024*1024+stack_maxrandom_size()
170 // We do not use any address space layout randomization in gem5
171 // therefore the random fields become zero; the smallest gap space was
172 // chosen but gap could potentially be much larger.
173 mmap_end = (Addr)0xB7FFF000ULL;
174}
175
176SyscallDesc*
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*
177X86LiveProcess::getDesc(int callnum)
175X86Process::getDesc(int callnum)
178{
179 if (callnum < 0 || callnum >= numSyscallDescs)
180 return NULL;
181 return &syscallDescs[callnum];
182}
183
184void
176{
177 if (callnum < 0 || callnum >= numSyscallDescs)
178 return NULL;
179 return &syscallDescs[callnum];
180}
181
182void
185X86_64LiveProcess::initState()
183X86_64Process::initState()
186{
184{
187 X86LiveProcess::initState();
185 X86Process::initState();
188
189 argsInit(sizeof(uint64_t), PageBytes);
190
191 // Set up the vsyscall page for this process.
192 allocateMem(vsyscallPage.base, vsyscallPage.size);
193 uint8_t vtimeBlob[] = {
194 0x48,0xc7,0xc0,0xc9,0x00,0x00,0x00, // mov $0xc9,%rax
195 0x0f,0x05, // syscall

--- 425 unchanged lines hidden (view full) ---

621 tc->setMiscReg(MISCREG_CR0, cr0);
622
623 tc->setMiscReg(MISCREG_MXCSR, 0x1f80);
624 }
625 }
626}
627
628void
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
629I386LiveProcess::initState()
627I386Process::initState()
630{
628{
631 X86LiveProcess::initState();
629 X86Process::initState();
632
633 argsInit(sizeof(uint32_t), PageBytes);
634
635 /*
636 * Set up a GDT for this process. The whole GDT wouldn't really be for
637 * this process, but the only parts we care about are.
638 */
639 allocateMem(_gdtStart, _gdtSize);

--- 101 unchanged lines hidden (view full) ---

741 tc->setMiscReg(MISCREG_CR0, cr0);
742
743 tc->setMiscReg(MISCREG_MXCSR, 0x1f80);
744 }
745}
746
747template<class IntType>
748void
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
749X86LiveProcess::argsInit(int pageSize,
747X86Process::argsInit(int pageSize,
750 std::vector<AuxVector<IntType> > extraAuxvs)
751{
752 int intSize = sizeof(IntType);
753
754 typedef AuxVector<IntType> auxv_t;
755 std::vector<auxv_t> auxv = extraAuxvs;
756
757 string filename;

--- 271 unchanged lines hidden (view full) ---

1029
1030 //Align the "stack_min" to a page boundary.
1031 stack_min = roundDown(stack_min, pageSize);
1032
1033// num_processes++;
1034}
1035
1036void
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
1037X86_64LiveProcess::argsInit(int intSize, int pageSize)
1035X86_64Process::argsInit(int intSize, int pageSize)
1038{
1039 std::vector<AuxVector<uint64_t> > extraAuxvs;
1040 extraAuxvs.push_back(AuxVector<uint64_t>(M5_AT_SYSINFO_EHDR,
1041 vsyscallPage.base));
1036{
1037 std::vector<AuxVector<uint64_t> > extraAuxvs;
1038 extraAuxvs.push_back(AuxVector<uint64_t>(M5_AT_SYSINFO_EHDR,
1039 vsyscallPage.base));
1042 X86LiveProcess::argsInit<uint64_t>(pageSize, extraAuxvs);
1040 X86Process::argsInit(pageSize, extraAuxvs);
1043}
1044
1045void
1041}
1042
1043void
1046I386LiveProcess::argsInit(int intSize, int pageSize)
1044I386Process::argsInit(int intSize, int pageSize)
1047{
1048 std::vector<AuxVector<uint32_t> > extraAuxvs;
1049 //Tell the binary where the vsyscall part of the vsyscall page is.
1050 extraAuxvs.push_back(AuxVector<uint32_t>(M5_AT_SYSINFO,
1051 vsyscallPage.base + vsyscallPage.vsyscallOffset));
1052 extraAuxvs.push_back(AuxVector<uint32_t>(M5_AT_SYSINFO_EHDR,
1053 vsyscallPage.base));
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));
1054 X86LiveProcess::argsInit<uint32_t>(pageSize, extraAuxvs);
1052 X86Process::argsInit(pageSize, extraAuxvs);
1055}
1056
1057void
1053}
1054
1055void
1058X86LiveProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn retval)
1056X86Process::setSyscallReturn(ThreadContext *tc, SyscallReturn retval)
1059{
1060 tc->setIntReg(INTREG_RAX, retval.encodedValue());
1061}
1062
1063X86ISA::IntReg
1057{
1058 tc->setIntReg(INTREG_RAX, retval.encodedValue());
1059}
1060
1061X86ISA::IntReg
1064X86_64LiveProcess::getSyscallArg(ThreadContext *tc, int &i)
1062X86_64Process::getSyscallArg(ThreadContext *tc, int &i)
1065{
1066 assert(i < NumArgumentRegs);
1067 return tc->readIntReg(ArgumentReg[i++]);
1068}
1069
1070void
1063{
1064 assert(i < NumArgumentRegs);
1065 return tc->readIntReg(ArgumentReg[i++]);
1066}
1067
1068void
1071X86_64LiveProcess::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val)
1069X86_64Process::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val)
1072{
1073 assert(i < NumArgumentRegs);
1074 return tc->setIntReg(ArgumentReg[i], val);
1075}
1076
1077X86ISA::IntReg
1070{
1071 assert(i < NumArgumentRegs);
1072 return tc->setIntReg(ArgumentReg[i], val);
1073}
1074
1075X86ISA::IntReg
1078I386LiveProcess::getSyscallArg(ThreadContext *tc, int &i)
1076I386Process::getSyscallArg(ThreadContext *tc, int &i)
1079{
1080 assert(i < NumArgumentRegs32);
1081 return tc->readIntReg(ArgumentReg32[i++]);
1082}
1083
1084X86ISA::IntReg
1077{
1078 assert(i < NumArgumentRegs32);
1079 return tc->readIntReg(ArgumentReg32[i++]);
1080}
1081
1082X86ISA::IntReg
1085I386LiveProcess::getSyscallArg(ThreadContext *tc, int &i, int width)
1083I386Process::getSyscallArg(ThreadContext *tc, int &i, int width)
1086{
1087 assert(width == 32 || width == 64);
1088 assert(i < NumArgumentRegs);
1089 uint64_t retVal = tc->readIntReg(ArgumentReg32[i++]) & mask(32);
1090 if (width == 64)
1091 retVal |= ((uint64_t)tc->readIntReg(ArgumentReg[i++]) << 32);
1092 return retVal;
1093}
1094
1095void
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
1096I386LiveProcess::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val)
1094I386Process::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val)
1097{
1098 assert(i < NumArgumentRegs);
1099 return tc->setIntReg(ArgumentReg[i], val);
1100}
1095{
1096 assert(i < NumArgumentRegs);
1097 return tc->setIntReg(ArgumentReg[i], val);
1098}