process.cc (11884:e8536709cbc0) process.cc (11886:43b882cada33)
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{
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 brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
104 brk_point = roundUp(brk_point, PageBytes);
103 memState->brkPoint = objFile->dataBase() + objFile->dataSize()
104 + objFile->bssSize();
105 memState->brkPoint = roundUp(memState->brkPoint, PageBytes);
105}
106
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
107X86_64Process::X86_64Process(ProcessParams *params, ObjectFile *objFile,
108 SyscallDesc *_syscallDescs, int _numSyscallDescs)
109 : X86Process(params, objFile, _syscallDescs, _numSyscallDescs)
110{
111
112 vsyscallPage.base = 0xffffffffff600000ULL;
113 vsyscallPage.size = PageBytes;
114 vsyscallPage.vtimeOffset = 0x400;
115 vsyscallPage.vgettimeofdayOffset = 0x0;
116
117 // Set up stack. On X86_64 Linux, stack goes from the top of memory
118 // downward, less the hole for the kernel address space plus one page
119 // for undertermined purposes.
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.
120 stack_base = (Addr)0x7FFFFFFFF000ULL;
129 memState->stackBase = (Addr)0x7FFFFFFFF000ULL;
121
122 // Set pointer for next thread stack. Reserve 8M for main stack.
130
131 // Set pointer for next thread stack. Reserve 8M for main stack.
123 next_thread_stack_base = stack_base - (8 * 1024 * 1024);
132 memState->nextThreadStackBase = memState->stackBase - (8 * 1024 * 1024);
124
125 // "mmap_base" is a function which defines where mmap region starts in
126 // the process address space.
127 // mmap_base: PAGE_ALIGN(TASK_SIZE-MIN_GAP-mmap_rnd())
128 // TASK_SIZE: (1<<47)-PAGE_SIZE
129 // MIN_GAP: 128*1024*1024+stack_maxrandom_size()
130 // We do not use any address space layout randomization in gem5
131 // therefore the random fields become zero; the smallest gap space was
132 // chosen but gap could potentially be much larger.
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.
133 mmap_end = (Addr)0x7FFFF7FFF000ULL;
142 memState->mmapEnd = (Addr)0x7FFFF7FFF000ULL;
134}
135
136void
137I386Process::syscall(int64_t callnum, ThreadContext *tc, Fault *fault)
138{
139 TheISA::PCState pc = tc->pcState();
140 Addr eip = pc.pc();
141 if (eip >= vsyscallPage.base &&

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

154 _gdtStart = ULL(0xffffd000);
155 _gdtSize = PageBytes;
156
157 vsyscallPage.base = 0xffffe000ULL;
158 vsyscallPage.size = PageBytes;
159 vsyscallPage.vsyscallOffset = 0x400;
160 vsyscallPage.vsysexitOffset = 0x410;
161
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
162 stack_base = _gdtStart;
171 memState->stackBase = _gdtStart;
163
164 // Set pointer for next thread stack. Reserve 8M for main stack.
172
173 // Set pointer for next thread stack. Reserve 8M for main stack.
165 next_thread_stack_base = stack_base - (8 * 1024 * 1024);
174 memState->nextThreadStackBase = memState->stackBase - (8 * 1024 * 1024);
166
167 // "mmap_base" is a function which defines where mmap region starts in
168 // the process address space.
169 // mmap_base: PAGE_ALIGN(TASK_SIZE-MIN_GAP-mmap_rnd())
170 // TASK_SIZE: 0xC0000000
171 // MIN_GAP: 128*1024*1024+stack_maxrandom_size()
172 // We do not use any address space layout randomization in gem5
173 // therefore the random fields become zero; the smallest gap space was
174 // chosen but gap could potentially be much larger.
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.
175 mmap_end = (Addr)0xB7FFF000ULL;
184 memState->mmapEnd = (Addr)0xB7FFF000ULL;
176}
177
178SyscallDesc*
179X86Process::getDesc(int callnum)
180{
181 if (callnum < 0 || callnum >= numSyscallDescs)
182 return NULL;
183 return &syscallDescs[callnum];

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

941 int aux_padding = aligned_partial_size - partial_size;
942
943 int space_needed =
944 info_block_size +
945 aux_data_size +
946 aux_padding +
947 frame_size;
948
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
949 stack_min = stack_base - space_needed;
950 stack_min = roundDown(stack_min, align);
951 stack_size = roundUp(stack_base - stack_min, pageSize);
958 memState->stackMin = memState->stackBase - space_needed;
959 memState->stackMin = roundDown(memState->stackMin, align);
960 memState->stackSize = roundUp(memState->stackBase - memState->stackMin,
961 pageSize);
952
953 // map memory
962
963 // map memory
954 Addr stack_end = roundDown(stack_base - stack_size, pageSize);
964 Addr stack_end = roundDown(memState->stackBase - memState->stackSize,
965 pageSize);
955
966
956 DPRINTF(Stack, "Mapping the stack: 0x%x %dB\n", stack_end, stack_size);
957 allocateMem(stack_end, stack_size);
967 DPRINTF(Stack, "Mapping the stack: 0x%x %dB\n",
968 stack_end, memState->stackSize);
969 allocateMem(stack_end, memState->stackSize);
958
959 // map out initial stack contents
970
971 // map out initial stack contents
960 IntType sentry_base = stack_base - sentry_size;
972 IntType sentry_base = memState->stackBase - sentry_size;
961 IntType file_name_base = sentry_base - file_name_size;
962 IntType env_data_base = file_name_base - env_data_size;
963 IntType arg_data_base = env_data_base - arg_data_size;
964 IntType aux_data_base = arg_data_base - info_block_padding - aux_data_size;
965 IntType auxv_array_base = aux_data_base - aux_array_size - aux_padding;
966 IntType envp_array_base = auxv_array_base - envp_array_size;
967 IntType argv_array_base = envp_array_base - argv_array_size;
968 IntType argc_base = argv_array_base - argc_size;
969
970 DPRINTF(Stack, "The addresses of items on the initial stack:\n");
971 DPRINTF(Stack, "0x%x - file name\n", file_name_base);
972 DPRINTF(Stack, "0x%x - env data\n", env_data_base);
973 DPRINTF(Stack, "0x%x - arg data\n", arg_data_base);
974 DPRINTF(Stack, "0x%x - aux data\n", aux_data_base);
975 DPRINTF(Stack, "0x%x - auxv array\n", auxv_array_base);
976 DPRINTF(Stack, "0x%x - envp array\n", envp_array_base);
977 DPRINTF(Stack, "0x%x - argv array\n", argv_array_base);
978 DPRINTF(Stack, "0x%x - argc \n", argc_base);
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);
979 DPRINTF(Stack, "0x%x - stack min\n", stack_min);
991 DPRINTF(Stack, "0x%x - stack min\n", memState->stackMin);
980
981 // write contents to stack
982
983 // figure out argc
984 IntType argc = argv.size();
985 IntType guestArgc = X86ISA::htog(argc);
986
987 //Write out the sentry void *

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

1018
1019 copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
1020 copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
1021
1022 initVirtMem.writeBlob(argc_base, (uint8_t*)&guestArgc, intSize);
1023
1024 ThreadContext *tc = system->getThreadContext(contextIds[0]);
1025 //Set the stack pointer register
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
1026 tc->setIntReg(StackPointerReg, stack_min);
1038 tc->setIntReg(StackPointerReg, memState->stackMin);
1027
1028 // There doesn't need to be any segment base added in since we're dealing
1029 // with the flat segmentation model.
1030 tc->pcState(getStartPC());
1031
1032 //Align the "stack_min" to a page boundary.
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.
1033 stack_min = roundDown(stack_min, pageSize);
1045 memState->stackMin = roundDown(memState->stackMin, pageSize);
1034}
1035
1036void
1037X86_64Process::argsInit(int pageSize)
1038{
1039 std::vector<AuxVector<uint64_t> > extraAuxvs;
1040 extraAuxvs.push_back(AuxVector<uint64_t>(M5_AT_SYSINFO_EHDR,
1041 vsyscallPage.base));

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

1069
1070void
1071X86_64Process::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val)
1072{
1073 assert(i < NumArgumentRegs);
1074 return tc->setIntReg(ArgumentReg[i], val);
1075}
1076
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
1077X86ISA::IntReg
1078I386Process::getSyscallArg(ThreadContext *tc, int &i)
1079{
1080 assert(i < NumArgumentRegs32);
1081 return tc->readIntReg(ArgumentReg32[i++]);
1082}
1083
1084X86ISA::IntReg

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

1093}
1094
1095void
1096I386Process::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val)
1097{
1098 assert(i < NumArgumentRegs);
1099 return tc->setIntReg(ArgumentReg[i], val);
1100}
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}