gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
process.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010, 2012 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Copyright (c) 2007-2008 The Florida State University
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are
19  * met: redistributions of source code must retain the above copyright
20  * notice, this list of conditions and the following disclaimer;
21  * redistributions in binary form must reproduce the above copyright
22  * notice, this list of conditions and the following disclaimer in the
23  * documentation and/or other materials provided with the distribution;
24  * neither the name of the copyright holders nor the names of its
25  * contributors may be used to endorse or promote products derived from
26  * this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  *
40  * Authors: Stephen Hines
41  * Ali Saidi
42  */
43 
44 #include "arch/arm/process.hh"
45 
46 #include "arch/arm/isa_traits.hh"
47 #include "arch/arm/types.hh"
50 #include "base/misc.hh"
51 #include "cpu/thread_context.hh"
52 #include "debug/Stack.hh"
53 #include "mem/page_table.hh"
54 #include "sim/aux_vector.hh"
55 #include "sim/byteswap.hh"
56 #include "sim/process_impl.hh"
57 #include "sim/syscall_return.hh"
58 #include "sim/system.hh"
59 
60 using namespace std;
61 using namespace ArmISA;
62 
63 ArmProcess::ArmProcess(ProcessParams *params, ObjectFile *objFile,
64  ObjectFile::Arch _arch)
65  : Process(params, objFile), arch(_arch)
66 {
67 }
68 
69 ArmProcess32::ArmProcess32(ProcessParams *params, ObjectFile *objFile,
70  ObjectFile::Arch _arch)
71  : ArmProcess(params, objFile, _arch)
72 {
73  Addr brk_point = roundUp(objFile->dataBase() + objFile->dataSize() +
74  objFile->bssSize(), PageBytes);
75  Addr stack_base = 0xbf000000L;
76  Addr max_stack_size = 8 * 1024 * 1024;
77  Addr next_thread_stack_base = stack_base - max_stack_size;
78  Addr mmap_end = 0x40000000L;
79 
80  memState = make_shared<MemState>(brk_point, stack_base, max_stack_size,
81  next_thread_stack_base, mmap_end);
82 }
83 
84 ArmProcess64::ArmProcess64(ProcessParams *params, ObjectFile *objFile,
85  ObjectFile::Arch _arch)
86  : ArmProcess(params, objFile, _arch)
87 {
88  Addr brk_point = roundUp(objFile->dataBase() + objFile->dataSize() +
89  objFile->bssSize(), PageBytes);
90  Addr stack_base = 0x7fffff0000L;
91  Addr max_stack_size = 8 * 1024 * 1024;
92  Addr next_thread_stack_base = stack_base - max_stack_size;
93  Addr mmap_end = 0x4000000000L;
94 
95  memState = make_shared<MemState>(brk_point, stack_base, max_stack_size,
96  next_thread_stack_base, mmap_end);
97 }
98 
99 void
101 {
103  argsInit<uint32_t>(PageBytes, INTREG_SP);
104  for (int i = 0; i < contextIds.size(); i++) {
106  CPACR cpacr = tc->readMiscReg(MISCREG_CPACR);
107  // Enable the floating point coprocessors.
108  cpacr.cp10 = 0x3;
109  cpacr.cp11 = 0x3;
110  tc->setMiscReg(MISCREG_CPACR, cpacr);
111  // Generically enable floating point support.
112  FPEXC fpexc = tc->readMiscReg(MISCREG_FPEXC);
113  fpexc.en = 1;
114  tc->setMiscReg(MISCREG_FPEXC, fpexc);
115  }
116 }
117 
118 void
120 {
122  argsInit<uint64_t>(PageBytes, INTREG_SP0);
123  for (int i = 0; i < contextIds.size(); i++) {
125  CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
126  cpsr.mode = MODE_EL0T;
127  tc->setMiscReg(MISCREG_CPSR, cpsr);
128  CPACR cpacr = tc->readMiscReg(MISCREG_CPACR_EL1);
129  // Enable the floating point coprocessors.
130  cpacr.cp10 = 0x3;
131  cpacr.cp11 = 0x3;
132  tc->setMiscReg(MISCREG_CPACR_EL1, cpacr);
133  // Generically enable floating point support.
134  FPEXC fpexc = tc->readMiscReg(MISCREG_FPEXC);
135  fpexc.en = 1;
136  tc->setMiscReg(MISCREG_FPEXC, fpexc);
137  }
138 }
139 
140 template <class IntType>
141 void
142 ArmProcess::argsInit(int pageSize, IntRegIndex spIndex)
143 {
144  int intSize = sizeof(IntType);
145 
146  typedef AuxVector<IntType> auxv_t;
147  std::vector<auxv_t> auxv;
148 
149  string filename;
150  if (argv.size() < 1)
151  filename = "";
152  else
153  filename = argv[0];
154 
155  //We want 16 byte alignment
156  uint64_t align = 16;
157 
158  // Patch the ld_bias for dynamic executables.
159  updateBias();
160 
161  // load object file into target memory
163 
164  enum ArmCpuFeature {
165  Arm_Swp = 1 << 0,
166  Arm_Half = 1 << 1,
167  Arm_Thumb = 1 << 2,
168  Arm_26Bit = 1 << 3,
169  Arm_FastMult = 1 << 4,
170  Arm_Fpa = 1 << 5,
171  Arm_Vfp = 1 << 6,
172  Arm_Edsp = 1 << 7,
173  Arm_Java = 1 << 8,
174  Arm_Iwmmxt = 1 << 9,
175  Arm_Crunch = 1 << 10,
176  Arm_ThumbEE = 1 << 11,
177  Arm_Neon = 1 << 12,
178  Arm_Vfpv3 = 1 << 13,
179  Arm_Vfpv3d16 = 1 << 14
180  };
181 
182  //Setup the auxilliary vectors. These will already have endian conversion.
183  //Auxilliary vectors are loaded only for elf formatted executables.
184  ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
185  if (elfObject) {
186 
187  if (objFile->getOpSys() == ObjectFile::Linux) {
188  IntType features =
189  Arm_Swp |
190  Arm_Half |
191  Arm_Thumb |
192 // Arm_26Bit |
193  Arm_FastMult |
194 // Arm_Fpa |
195  Arm_Vfp |
196  Arm_Edsp |
197 // Arm_Java |
198 // Arm_Iwmmxt |
199 // Arm_Crunch |
200  Arm_ThumbEE |
201  Arm_Neon |
202  Arm_Vfpv3 |
203  Arm_Vfpv3d16 |
204  0;
205 
206  //Bits which describe the system hardware capabilities
207  //XXX Figure out what these should be
208  auxv.push_back(auxv_t(M5_AT_HWCAP, features));
209  //Frequency at which times() increments
210  auxv.push_back(auxv_t(M5_AT_CLKTCK, 0x64));
211  //Whether to enable "secure mode" in the executable
212  auxv.push_back(auxv_t(M5_AT_SECURE, 0));
213  // Pointer to 16 bytes of random data
214  auxv.push_back(auxv_t(M5_AT_RANDOM, 0));
215  //The filename of the program
216  auxv.push_back(auxv_t(M5_AT_EXECFN, 0));
217  //The string "v71" -- ARM v7 architecture
218  auxv.push_back(auxv_t(M5_AT_PLATFORM, 0));
219  }
220 
221  //The system page size
222  auxv.push_back(auxv_t(M5_AT_PAGESZ, ArmISA::PageBytes));
223  // For statically linked executables, this is the virtual address of the
224  // program header tables if they appear in the executable image
225  auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable()));
226  // This is the size of a program header entry from the elf file.
227  auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize()));
228  // This is the number of program headers from the original elf file.
229  auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount()));
230  // This is the base address of the ELF interpreter; it should be
231  // zero for static executables or contain the base address for
232  // dynamic executables.
233  auxv.push_back(auxv_t(M5_AT_BASE, getBias()));
234  //XXX Figure out what this should be.
235  auxv.push_back(auxv_t(M5_AT_FLAGS, 0));
236  //The entry point to the program
237  auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint()));
238  //Different user and group IDs
239  auxv.push_back(auxv_t(M5_AT_UID, uid()));
240  auxv.push_back(auxv_t(M5_AT_EUID, euid()));
241  auxv.push_back(auxv_t(M5_AT_GID, gid()));
242  auxv.push_back(auxv_t(M5_AT_EGID, egid()));
243  }
244 
245  //Figure out how big the initial stack nedes to be
246 
247  // A sentry NULL void pointer at the top of the stack.
248  int sentry_size = intSize;
249 
250  string platform = "v71";
251  int platform_size = platform.size() + 1;
252 
253  // Bytes for AT_RANDOM above, we'll just keep them 0
254  int aux_random_size = 16; // as per the specification
255 
256  // The aux vectors are put on the stack in two groups. The first group are
257  // the vectors that are generated as the elf is loaded. The second group
258  // are the ones that were computed ahead of time and include the platform
259  // string.
260  int aux_data_size = filename.size() + 1;
261 
262  int env_data_size = 0;
263  for (int i = 0; i < envp.size(); ++i) {
264  env_data_size += envp[i].size() + 1;
265  }
266  int arg_data_size = 0;
267  for (int i = 0; i < argv.size(); ++i) {
268  arg_data_size += argv[i].size() + 1;
269  }
270 
271  int info_block_size =
272  sentry_size + env_data_size + arg_data_size +
273  aux_data_size + platform_size + aux_random_size;
274 
275  //Each auxilliary vector is two 4 byte words
276  int aux_array_size = intSize * 2 * (auxv.size() + 1);
277 
278  int envp_array_size = intSize * (envp.size() + 1);
279  int argv_array_size = intSize * (argv.size() + 1);
280 
281  int argc_size = intSize;
282 
283  //Figure out the size of the contents of the actual initial frame
284  int frame_size =
285  info_block_size +
286  aux_array_size +
287  envp_array_size +
288  argv_array_size +
289  argc_size;
290 
291  //There needs to be padding after the auxiliary vector data so that the
292  //very bottom of the stack is aligned properly.
293  int partial_size = frame_size;
294  int aligned_partial_size = roundUp(partial_size, align);
295  int aux_padding = aligned_partial_size - partial_size;
296 
297  int space_needed = frame_size + aux_padding;
298 
299  memState->setStackMin(memState->getStackBase() - space_needed);
300  memState->setStackMin(roundDown(memState->getStackMin(), align));
301  memState->setStackSize(memState->getStackBase() - memState->getStackMin());
302 
303  // map memory
304  allocateMem(roundDown(memState->getStackMin(), pageSize),
305  roundUp(memState->getStackSize(), pageSize));
306 
307  // map out initial stack contents
308  IntType sentry_base = memState->getStackBase() - sentry_size;
309  IntType aux_data_base = sentry_base - aux_data_size;
310  IntType env_data_base = aux_data_base - env_data_size;
311  IntType arg_data_base = env_data_base - arg_data_size;
312  IntType platform_base = arg_data_base - platform_size;
313  IntType aux_random_base = platform_base - aux_random_size;
314  IntType auxv_array_base = aux_random_base - aux_array_size - aux_padding;
315  IntType envp_array_base = auxv_array_base - envp_array_size;
316  IntType argv_array_base = envp_array_base - argv_array_size;
317  IntType argc_base = argv_array_base - argc_size;
318 
319  DPRINTF(Stack, "The addresses of items on the initial stack:\n");
320  DPRINTF(Stack, "0x%x - aux data\n", aux_data_base);
321  DPRINTF(Stack, "0x%x - env data\n", env_data_base);
322  DPRINTF(Stack, "0x%x - arg data\n", arg_data_base);
323  DPRINTF(Stack, "0x%x - random data\n", aux_random_base);
324  DPRINTF(Stack, "0x%x - platform base\n", platform_base);
325  DPRINTF(Stack, "0x%x - auxv array\n", auxv_array_base);
326  DPRINTF(Stack, "0x%x - envp array\n", envp_array_base);
327  DPRINTF(Stack, "0x%x - argv array\n", argv_array_base);
328  DPRINTF(Stack, "0x%x - argc \n", argc_base);
329  DPRINTF(Stack, "0x%x - stack min\n", memState->getStackMin());
330 
331  // write contents to stack
332 
333  // figure out argc
334  IntType argc = argv.size();
335  IntType guestArgc = ArmISA::htog(argc);
336 
337  //Write out the sentry void *
338  IntType sentry_NULL = 0;
339  initVirtMem.writeBlob(sentry_base,
340  (uint8_t*)&sentry_NULL, sentry_size);
341 
342  //Fix up the aux vectors which point to other data
343  for (int i = auxv.size() - 1; i >= 0; i--) {
344  if (auxv[i].a_type == M5_AT_PLATFORM) {
345  auxv[i].a_val = platform_base;
346  initVirtMem.writeString(platform_base, platform.c_str());
347  } else if (auxv[i].a_type == M5_AT_EXECFN) {
348  auxv[i].a_val = aux_data_base;
349  initVirtMem.writeString(aux_data_base, filename.c_str());
350  } else if (auxv[i].a_type == M5_AT_RANDOM) {
351  auxv[i].a_val = aux_random_base;
352  // Just leave the value 0, we don't want randomness
353  }
354  }
355 
356  //Copy the aux stuff
357  for (int x = 0; x < auxv.size(); x++) {
358  initVirtMem.writeBlob(auxv_array_base + x * 2 * intSize,
359  (uint8_t*)&(auxv[x].a_type), intSize);
360  initVirtMem.writeBlob(auxv_array_base + (x * 2 + 1) * intSize,
361  (uint8_t*)&(auxv[x].a_val), intSize);
362  }
363  //Write out the terminating zeroed auxilliary vector
364  const uint64_t zero = 0;
365  initVirtMem.writeBlob(auxv_array_base + 2 * intSize * auxv.size(),
366  (uint8_t*)&zero, 2 * intSize);
367 
368  copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
369  copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
370 
371  initVirtMem.writeBlob(argc_base, (uint8_t*)&guestArgc, intSize);
372 
374  //Set the stack pointer register
375  tc->setIntReg(spIndex, memState->getStackMin());
376  //A pointer to a function to run when the program exits. We'll set this
377  //to zero explicitly to make sure this isn't used.
378  tc->setIntReg(ArgumentReg0, 0);
379  //Set argument regs 1 and 2 to argv[0] and envp[0] respectively
380  if (argv.size() > 0) {
381  tc->setIntReg(ArgumentReg1, arg_data_base + arg_data_size -
382  argv[argv.size() - 1].size() - 1);
383  } else {
384  tc->setIntReg(ArgumentReg1, 0);
385  }
386  if (envp.size() > 0) {
387  tc->setIntReg(ArgumentReg2, env_data_base + env_data_size -
388  envp[envp.size() - 1].size() - 1);
389  } else {
390  tc->setIntReg(ArgumentReg2, 0);
391  }
392 
393  PCState pc;
394  pc.thumb(arch == ObjectFile::Thumb);
395  pc.nextThumb(pc.thumb());
396  pc.aarch64(arch == ObjectFile::Arm64);
397  pc.nextAArch64(pc.aarch64());
398  pc.set(getStartPC() & ~mask(1));
399  tc->pcState(pc);
400 
401  //Align the "stackMin" to a page boundary.
402  memState->setStackMin(roundDown(memState->getStackMin(), pageSize));
403 }
404 
407 {
408  assert(i < 6);
409  return tc->readIntReg(ArgumentReg0 + i++);
410 }
411 
414 {
415  assert(i < 8);
416  return tc->readIntReg(ArgumentReg0 + i++);
417 }
418 
421 {
422  assert(width == 32 || width == 64);
423  if (width == 32)
424  return getSyscallArg(tc, i);
425 
426  // 64 bit arguments are passed starting in an even register
427  if (i % 2 != 0)
428  i++;
429 
430  // Registers r0-r6 can be used
431  assert(i < 5);
432  uint64_t val;
433  val = tc->readIntReg(ArgumentReg0 + i++);
434  val |= ((uint64_t)tc->readIntReg(ArgumentReg0 + i++) << 32);
435  return val;
436 }
437 
440 {
441  return getSyscallArg(tc, i);
442 }
443 
444 
445 void
447 {
448  assert(i < 6);
449  tc->setIntReg(ArgumentReg0 + i, val);
450 }
451 
452 void
454 {
455  assert(i < 8);
456  tc->setIntReg(ArgumentReg0 + i, val);
457 }
458 
459 void
461 {
462 
464  // Decode return value
465  if (sysret.encodedValue() >= 0)
466  // FreeBSD checks the carry bit to determine if syscall is succeeded
467  tc->setCCReg(CCREG_C, 0);
468  else {
469  sysret = -sysret.encodedValue();
470  }
471  }
472 
473  tc->setIntReg(ReturnValueReg, sysret.encodedValue());
474 }
475 
476 void
478 {
479 
481  // Decode return value
482  if (sysret.encodedValue() >= 0)
483  // FreeBSD checks the carry bit to determine if syscall is succeeded
484  tc->setCCReg(CCREG_C, 0);
485  else {
486  sysret = -sysret.encodedValue();
487  }
488  }
489 
490  tc->setIntReg(ReturnValueReg, sysret.encodedValue());
491 }
Addr dataBase() const
Definition: object_file.hh:139
#define DPRINTF(x,...)
Definition: trace.hh:212
ObjectFile * objFile
Definition: process.hh:182
T htog(T value)
Definition: byteswap.hh:177
Addr programHeaderTable()
Definition: elf_object.hh:129
Bitfield< 7, 0 > L
Definition: int.hh:59
IntRegIndex
Definition: intregs.hh:53
Bitfield< 7 > i
Definition: miscregs.hh:1378
const int ArgumentReg0
Definition: registers.hh:97
std::vector< ContextID > contextIds
Definition: process.hh:168
ArmISA::IntReg getSyscallArg(ThreadContext *tc, int &i, int width)
Definition: process.cc:439
void allocateMem(Addr vaddr, int64_t size, bool clobber=false)
Definition: process.cc:310
SETranslatingPortProxy initVirtMem
Definition: process.hh:180
uint64_t uid()
Definition: process.hh:83
virtual void setMiscReg(int misc_reg, const MiscReg &val)=0
const int ArgumentReg2
Definition: registers.hh:99
virtual void setIntReg(int reg_idx, uint64_t val)=0
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
Definition: process.cc:288
virtual TheISA::PCState pcState()=0
T roundUp(const T &val, const U &align)
Definition: intmath.hh:205
std::shared_ptr< MemState > memState
Definition: process.hh:206
ThreadContext is the external interface to all thread state for anything outside of the CPU...
STL vector class.
Definition: stl.hh:40
Bitfield< 63 > val
Definition: misc.hh:770
void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value)
Definition: process.cc:477
uint64_t IntReg
Definition: registers.hh:63
virtual void setCCReg(int reg_idx, CCReg val)=0
void setSyscallArg(ThreadContext *tc, int i, ArmISA::IntReg val)
Definition: process.cc:446
virtual uint64_t readIntReg(int reg_idx)=0
ArmProcess(ProcessParams *params, ObjectFile *objFile, ObjectFile::Arch _arch)
Definition: process.cc:63
ObjectFile::Arch arch
Definition: process.hh:59
uint64_t euid()
Definition: process.hh:84
void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value)
Definition: process.cc:460
Addr getStartPC()
Definition: process.cc:482
void initState()
initState() is called on each SimObject when not restoring from a checkpoint.
Definition: process.cc:100
System * system
Definition: process.hh:171
T roundDown(const T &val, const U &align)
Definition: intmath.hh:213
Addr entryPoint() const
Definition: object_file.hh:134
std::vector< std::string > envp
Definition: process.hh:184
ThreadContext * getThreadContext(ContextID tid)
Definition: system.hh:203
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
void setSyscallArg(ThreadContext *tc, int i, ArmISA::IntReg val)
Definition: process.cc:453
virtual bool loadSections(PortProxy &mem_proxy, Addr mask=maxAddr, Addr offset=0)
Definition: object_file.cc:93
size_t dataSize() const
Definition: object_file.hh:143
const Addr PageBytes
Definition: isa_traits.hh:52
uint16_t programHeaderSize()
Definition: elf_object.hh:130
void copyStringArray(std::vector< std::string > &strings, AddrType array_ptr, AddrType data_ptr, SETranslatingPortProxy &memProxy)
Definition: process_impl.hh:43
virtual MiscReg readMiscReg(int misc_reg)=0
void writeString(Addr addr, const char *str) const
Declarations of a non-full system Page Table.
uint16_t programHeaderCount()
Definition: elf_object.hh:131
void updateBias()
Definition: process.cc:442
ArmProcess64(ProcessParams *params, ObjectFile *objFile, ObjectFile::Arch _arch)
Definition: process.cc:84
GenericISA::SimplePCState< MachInst > PCState
Definition: types.hh:43
ArmISA::IntReg getSyscallArg(ThreadContext *tc, int &i, int width)
Definition: process.cc:420
int64_t encodedValue() const
The encoded value (as described above)
size_t bssSize() const
Definition: object_file.hh:144
void argsInit(int pageSize, ArmISA::IntRegIndex spIndex)
Definition: process.cc:142
Bitfield< 4 > width
Definition: miscregs.hh:1383
ArmProcess32(ProcessParams *params, ObjectFile *objFile, ObjectFile::Arch _arch)
Definition: process.cc:69
uint64_t gid()
Definition: process.hh:85
const Addr PageBytes
Definition: isa_traits.hh:64
IntReg pc
Definition: remote_gdb.hh:91
Bitfield< 3, 0 > mask
Definition: types.hh:64
const RegIndex ReturnValueReg
Definition: registers.hh:83
std::vector< std::string > argv
Definition: process.hh:183
This class represents the return value from an emulated system call, including any errno setting...
Bitfield< 1 > x
Definition: types.hh:105
const int ArgumentReg1
Definition: registers.hh:98
Addr getBias()
Definition: process.cc:474
uint64_t egid()
Definition: process.hh:86
virtual void writeBlob(Addr addr, const uint8_t *p, int size) const
Write size bytes from p to address.
OpSys getOpSys() const
Definition: object_file.hh:112
void initState()
initState() is called on each SimObject when not restoring from a checkpoint.
Definition: process.cc:119

Generated on Fri Jun 9 2017 13:03:35 for gem5 by doxygen 1.8.6