Deleted Added
sdiff udiff text old ( 11800:54436a1784dc ) new ( 11851:824055fe6b30 )
full compact
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)
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)
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
134I386LiveProcess::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 }
143 X86LiveProcess::syscall(callnum, tc);
144}
145
146
147I386LiveProcess::I386LiveProcess(LiveProcessParams *params,
148 ObjectFile *objFile, SyscallDesc *_syscallDescs,
149 int _numSyscallDescs) :
150 X86LiveProcess(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*
177X86LiveProcess::getDesc(int callnum)
178{
179 if (callnum < 0 || callnum >= numSyscallDescs)
180 return NULL;
181 return &syscallDescs[callnum];
182}
183
184void
185X86_64LiveProcess::initState()
186{
187 X86LiveProcess::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
629I386LiveProcess::initState()
630{
631 X86LiveProcess::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
749X86LiveProcess::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
1037X86_64LiveProcess::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));
1042 X86LiveProcess::argsInit<uint64_t>(pageSize, extraAuxvs);
1043}
1044
1045void
1046I386LiveProcess::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));
1054 X86LiveProcess::argsInit<uint32_t>(pageSize, extraAuxvs);
1055}
1056
1057void
1058X86LiveProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn retval)
1059{
1060 tc->setIntReg(INTREG_RAX, retval.encodedValue());
1061}
1062
1063X86ISA::IntReg
1064X86_64LiveProcess::getSyscallArg(ThreadContext *tc, int &i)
1065{
1066 assert(i < NumArgumentRegs);
1067 return tc->readIntReg(ArgumentReg[i++]);
1068}
1069
1070void
1071X86_64LiveProcess::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val)
1072{
1073 assert(i < NumArgumentRegs);
1074 return tc->setIntReg(ArgumentReg[i], val);
1075}
1076
1077X86ISA::IntReg
1078I386LiveProcess::getSyscallArg(ThreadContext *tc, int &i)
1079{
1080 assert(i < NumArgumentRegs32);
1081 return tc->readIntReg(ArgumentReg32[i++]);
1082}
1083
1084X86ISA::IntReg
1085I386LiveProcess::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
1096I386LiveProcess::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val)
1097{
1098 assert(i < NumArgumentRegs);
1099 return tc->setIntReg(ArgumentReg[i], val);
1100}