mem-cache: Add multiple eviction stats
[gem5.git] / src / arch / x86 / process.cc
index 1e6401b10e6ebbb84bc395a2fb0e1b2ba40038bf..f270b2d8f258c0ca645b65e580ec20ed272d8639 100644 (file)
 #include "arch/x86/types.hh"
 #include "base/loader/elf_object.hh"
 #include "base/loader/object_file.hh"
-#include "base/misc.hh"
+#include "base/logging.hh"
 #include "base/trace.hh"
 #include "cpu/thread_context.hh"
 #include "debug/Stack.hh"
 #include "mem/multi_level_page_table.hh"
 #include "mem/page_table.hh"
+#include "params/Process.hh"
 #include "sim/aux_vector.hh"
 #include "sim/process_impl.hh"
 #include "sim/syscall_desc.hh"
@@ -73,9 +74,9 @@ static const int ArgumentReg[] = {
     INTREG_RDI,
     INTREG_RSI,
     INTREG_RDX,
-    //This argument register is r10 for syscalls and rcx for C.
+    // This argument register is r10 for syscalls and rcx for C.
     INTREG_R10W,
-    //INTREG_RCX,
+    // INTREG_RCX,
     INTREG_R8W,
     INTREG_R9W
 };
@@ -95,15 +96,30 @@ static const int ArgumentReg32[] = {
 static const int NumArgumentRegs32 M5_VAR_USED =
     sizeof(ArgumentReg) / sizeof(const int);
 
-X86Process::X86Process(ProcessParams * params, ObjectFile *objFile,
+template class MultiLevelPageTable<LongModePTE<47, 39>,
+                                   LongModePTE<38, 30>,
+                                   LongModePTE<29, 21>,
+                                   LongModePTE<20, 12> >;
+typedef MultiLevelPageTable<LongModePTE<47, 39>,
+                            LongModePTE<38, 30>,
+                            LongModePTE<29, 21>,
+                            LongModePTE<20, 12> > ArchPageTable;
+
+X86Process::X86Process(ProcessParams *params, ObjectFile *objFile,
                        SyscallDesc *_syscallDescs, int _numSyscallDescs)
-    : Process(params, objFile), syscallDescs(_syscallDescs),
-      numSyscallDescs(_numSyscallDescs)
+    : Process(params, params->useArchPT ?
+                      static_cast<EmulationPageTable *>(
+                              new ArchPageTable(params->name, params->pid,
+                                                params->system, PageBytes)) :
+                      new EmulationPageTable(params->name, params->pid,
+                                             PageBytes),
+              objFile),
+      syscallDescs(_syscallDescs), numSyscallDescs(_numSyscallDescs)
 {
 }
 
 void X86Process::clone(ThreadContext *old_tc, ThreadContext *new_tc,
-                       Process *p, TheISA::IntReg flags)
+                       Process *p, RegVal flags)
 {
     Process::clone(old_tc, new_tc, p, flags);
     X86Process *process = (X86Process*)p;
@@ -120,8 +136,7 @@ X86_64Process::X86_64Process(ProcessParams *params, ObjectFile *objFile,
     vsyscallPage.vtimeOffset = 0x400;
     vsyscallPage.vgettimeofdayOffset = 0x0;
 
-    Addr brk_point = roundUp(objFile->dataBase() + objFile->dataSize() +
-                             objFile->bssSize(), PageBytes);
+    Addr brk_point = roundUp(image.maxAddr(), PageBytes);
     Addr stack_base = 0x7FFFFFFFF000ULL;
     Addr max_stack_size = 8 * 1024 * 1024;
     Addr next_thread_stack_base = stack_base - max_stack_size;
@@ -131,24 +146,14 @@ X86_64Process::X86_64Process(ProcessParams *params, ObjectFile *objFile,
                                      next_thread_stack_base, mmap_end);
 }
 
-void
-I386Process::syscall(int64_t callnum, ThreadContext *tc, Fault *fault)
-{
-    TheISA::PCState pc = tc->pcState();
-    Addr eip = pc.pc();
-    if (eip >= vsyscallPage.base &&
-            eip < vsyscallPage.base + vsyscallPage.size) {
-        pc.npc(vsyscallPage.base + vsyscallPage.vsysexitOffset);
-        tc->pcState(pc);
-    }
-    X86Process::syscall(callnum, tc, fault);
-}
-
 
 I386Process::I386Process(ProcessParams *params, ObjectFile *objFile,
                          SyscallDesc *_syscallDescs, int _numSyscallDescs)
     : X86Process(params, objFile, _syscallDescs, _numSyscallDescs)
 {
+    if (kvmInSE)
+        panic("KVM CPU model does not support 32 bit processes");
+
     _gdtStart = ULL(0xffffd000);
     _gdtSize = PageBytes;
 
@@ -157,8 +162,7 @@ I386Process::I386Process(ProcessParams *params, ObjectFile *objFile,
     vsyscallPage.vsyscallOffset = 0x400;
     vsyscallPage.vsysexitOffset = 0x410;
 
-    Addr brk_point = roundUp(objFile->dataBase() + objFile->dataSize() +
-                             objFile->bssSize(), PageBytes);
+    Addr brk_point = roundUp(image.maxAddr(), PageBytes);
     Addr stack_base = _gdtStart;
     Addr max_stack_size = 8 * 1024 * 1024;
     Addr next_thread_stack_base = stack_base - max_stack_size;
@@ -181,9 +185,12 @@ X86_64Process::initState()
 {
     X86Process::initState();
 
+    if (useForClone)
+        return;
+
     argsInit(PageBytes);
 
-       // Set up the vsyscall page for this process.
+    // Set up the vsyscall page for this process.
     allocateMem(vsyscallPage.base, vsyscallPage.size);
     uint8_t vtimeBlob[] = {
         0x48,0xc7,0xc0,0xc9,0x00,0x00,0x00,    // mov    $0xc9,%rax
@@ -204,13 +211,20 @@ X86_64Process::initState()
     if (kvmInSE) {
         PortProxy physProxy = system->physProxy;
 
+        Addr syscallCodePhysAddr = system->allocPhysPages(1);
+        Addr gdtPhysAddr = system->allocPhysPages(1);
+        Addr idtPhysAddr = system->allocPhysPages(1);
+        Addr istPhysAddr = system->allocPhysPages(1);
+        Addr tssPhysAddr = system->allocPhysPages(1);
+        Addr pfHandlerPhysAddr = system->allocPhysPages(1);
+
         /*
          * Set up the gdt.
          */
         uint8_t numGDTEntries = 0;
         uint64_t nullDescriptor = 0;
-        physProxy.writeBlob(GDTPhysAddr + numGDTEntries * 8,
-                            (uint8_t *)(&nullDescriptor), 8);
+        physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
+                            &nullDescriptor, 8);
         numGDTEntries++;
 
         SegDescriptor initDesc = 0;
@@ -221,20 +235,18 @@ X86_64Process::initState()
         initDesc.p = 1;               // present
         initDesc.l = 1;               // longmode - 64 bit
         initDesc.d = 0;               // operand size
-        initDesc.g = 1;               // granularity
+        initDesc.g = 1;
         initDesc.s = 1;               // system segment
-        initDesc.limitHigh = 0xFFFF;
-        initDesc.limitLow = 0xF;
-        initDesc.baseHigh = 0x0;
-        initDesc.baseLow = 0x0;
+        initDesc.limit = 0xFFFFFFFF;
+        initDesc.base = 0;
 
         //64 bit code segment
         SegDescriptor csLowPLDesc = initDesc;
         csLowPLDesc.type.codeOrData = 1;
         csLowPLDesc.dpl = 0;
         uint64_t csLowPLDescVal = csLowPLDesc;
-        physProxy.writeBlob(GDTPhysAddr + numGDTEntries * 8,
-                            (uint8_t *)(&csLowPLDescVal), 8);
+        physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
+                            &csLowPLDescVal, 8);
 
         numGDTEntries++;
 
@@ -247,8 +259,8 @@ X86_64Process::initState()
         dsLowPLDesc.type.codeOrData = 0;
         dsLowPLDesc.dpl = 0;
         uint64_t dsLowPLDescVal = dsLowPLDesc;
-        physProxy.writeBlob(GDTPhysAddr + numGDTEntries * 8,
-                            (uint8_t *)(&dsLowPLDescVal), 8);
+        physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
+                            &dsLowPLDescVal, 8);
 
         numGDTEntries++;
 
@@ -261,8 +273,8 @@ X86_64Process::initState()
         dsDesc.type.codeOrData = 0;
         dsDesc.dpl = 3;
         uint64_t dsDescVal = dsDesc;
-        physProxy.writeBlob(GDTPhysAddr + numGDTEntries * 8,
-                            (uint8_t *)(&dsDescVal), 8);
+        physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
+                            &dsDescVal, 8);
 
         numGDTEntries++;
 
@@ -275,8 +287,8 @@ X86_64Process::initState()
         csDesc.type.codeOrData = 1;
         csDesc.dpl = 3;
         uint64_t csDescVal = csDesc;
-        physProxy.writeBlob(GDTPhysAddr + numGDTEntries * 8,
-                            (uint8_t *)(&csDescVal), 8);
+        physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
+                            &csDescVal, 8);
 
         numGDTEntries++;
 
@@ -297,11 +309,8 @@ X86_64Process::initState()
         TSSDescLow.type = 0xB;
         TSSDescLow.dpl = 0; // Privelege level 0
         TSSDescLow.p = 1; // Present
-        TSSDescLow.g = 1; // Page granularity
-        TSSDescLow.limitHigh = 0xF;
-        TSSDescLow.limitLow = 0xFFFF;
-        TSSDescLow.baseLow = bits(TSSVirtAddr, 23, 0);
-        TSSDescLow.baseHigh = bits(TSSVirtAddr, 31, 24);
+        TSSDescLow.limit = 0xFFFFFFFF;
+        TSSDescLow.base = bits(TSSVirtAddr, 31, 0);
 
         TSShigh TSSDescHigh = 0;
         TSSDescHigh.base = bits(TSSVirtAddr, 63, 32);
@@ -311,18 +320,16 @@ X86_64Process::initState()
             uint64_t high;
         } tssDescVal = {TSSDescLow, TSSDescHigh};
 
-        physProxy.writeBlob(GDTPhysAddr + numGDTEntries * 8,
-                            (uint8_t *)(&tssDescVal), sizeof(tssDescVal));
+        physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
+                            &tssDescVal, sizeof(tssDescVal));
 
         numGDTEntries++;
 
         SegSelector tssSel = 0;
         tssSel.si = numGDTEntries - 1;
 
-        uint64_t tss_base_addr = (TSSDescHigh.base << 32) |
-                                 (TSSDescLow.baseHigh << 24) |
-                                  TSSDescLow.baseLow;
-        uint64_t tss_limit = TSSDescLow.limitLow | (TSSDescLow.limitHigh << 16);
+        uint64_t tss_base_addr = (TSSDescHigh.base << 32) | TSSDescLow.base;
+        uint64_t tss_limit = TSSDescLow.limit;
 
         SegAttr tss_attr = 0;
 
@@ -370,8 +377,8 @@ X86_64Process::initState()
             efer.sce = 1; // Enable system call extensions.
             efer.lme = 1; // Enable long mode.
             efer.lma = 1; // Activate long mode.
-            efer.nxe = 0; // Enable nx support.
-            efer.svme = 1; // Enable svm support for now.
+            efer.nxe = 1; // Enable nx support.
+            efer.svme = 0; // Enable svm support for now.
             efer.ffxsr = 0; // Turn on fast fxsave and fxrstor.
             tc->setMiscReg(MISCREG_EFER, efer);
 
@@ -395,13 +402,13 @@ X86_64Process::initState()
             CR0 cr2 = 0;
             tc->setMiscReg(MISCREG_CR2, cr2);
 
-            CR3 cr3 = pageTablePhysAddr;
+            CR3 cr3 = dynamic_cast<ArchPageTable *>(pTable)->basePtr();
             tc->setMiscReg(MISCREG_CR3, cr3);
 
             CR4 cr4 = 0;
             //Turn on pae.
-            cr4.osxsave = 1; // Enable XSAVE and Proc Extended States
-            cr4.osxmmexcpt = 1; // Operating System Unmasked Exception
+            cr4.osxsave = 0; // Enable XSAVE and Proc Extended States
+            cr4.osxmmexcpt = 0; // Operating System Unmasked Exception
             cr4.osfxsr = 1; // Operating System FXSave/FSRSTOR Support
             cr4.pce = 0; // Performance-Monitoring Counter Enable
             cr4.pge = 0; // Page-Global Enable
@@ -418,10 +425,6 @@ X86_64Process::initState()
             CR4 cr8 = 0;
             tc->setMiscReg(MISCREG_CR8, cr8);
 
-            const Addr PageMapLevel4 = pageTablePhysAddr;
-            //Point to the page tables.
-            tc->setMiscReg(MISCREG_CR3, PageMapLevel4);
-
             tc->setMiscReg(MISCREG_MXCSR, 0x1f80);
 
             tc->setMiscReg(MISCREG_APIC_BASE, 0xfee00900);
@@ -433,11 +436,11 @@ X86_64Process::initState()
             tc->setMiscReg(MISCREG_IDTR_LIMIT, 0xffff);
 
             /* enabling syscall and sysret */
-            MiscReg star = ((MiscReg)sret << 48) | ((MiscReg)scall << 32);
+            RegVal star = ((RegVal)sret << 48) | ((RegVal)scall << 32);
             tc->setMiscReg(MISCREG_STAR, star);
-            MiscReg lstar = (MiscReg)syscallCodeVirtAddr;
+            RegVal lstar = (RegVal)syscallCodeVirtAddr;
             tc->setMiscReg(MISCREG_LSTAR, lstar);
-            MiscReg sfmask = (1 << 8) | (1 << 10); // TF | DF
+            RegVal sfmask = (1 << 8) | (1 << 10); // TF | DF
             tc->setMiscReg(MISCREG_SF_MASK, sfmask);
         }
 
@@ -483,7 +486,7 @@ X86_64Process::initState()
         tss.RSP1_high = tss.IST1_high;
         tss.RSP2_low  = tss.IST1_low;
         tss.RSP2_high = tss.IST1_high;
-        physProxy.writeBlob(TSSPhysAddr, (uint8_t *)(&tss), sizeof(tss));
+        physProxy.writeBlob(tssPhysAddr, &tss, sizeof(tss));
 
         /* Setting IDT gates */
         GateDescriptorLow PFGateLow = 0;
@@ -503,8 +506,7 @@ X86_64Process::initState()
             uint64_t high;
         } PFGate = {PFGateLow, PFGateHigh};
 
-        physProxy.writeBlob(IDTPhysAddr + 0xE0,
-                            (uint8_t *)(&PFGate), sizeof(PFGate));
+        physProxy.writeBlob(idtPhysAddr + 0xE0, &PFGate, sizeof(PFGate));
 
         /* System call handler */
         uint8_t syscallBlob[] = {
@@ -529,25 +531,24 @@ X86_64Process::initState()
             0x48, 0xcf
         };
 
-        physProxy.writeBlob(PFHandlerPhysAddr, faultBlob, sizeof(faultBlob));
-
-        MultiLevelPageTable<PageTableOps> *pt =
-            dynamic_cast<MultiLevelPageTable<PageTableOps> *>(pTable);
+        physProxy.writeBlob(pfHandlerPhysAddr, faultBlob, sizeof(faultBlob));
 
         /* Syscall handler */
-        pt->map(syscallCodeVirtAddr, syscallCodePhysAddr, PageBytes, false);
+        pTable->map(syscallCodeVirtAddr, syscallCodePhysAddr,
+                    PageBytes, false);
         /* GDT */
-        pt->map(GDTVirtAddr, GDTPhysAddr, PageBytes, false);
+        pTable->map(GDTVirtAddr, gdtPhysAddr, PageBytes, false);
         /* IDT */
-        pt->map(IDTVirtAddr, IDTPhysAddr, PageBytes, false);
+        pTable->map(IDTVirtAddr, idtPhysAddr, PageBytes, false);
         /* TSS */
-        pt->map(TSSVirtAddr, TSSPhysAddr, PageBytes, false);
+        pTable->map(TSSVirtAddr, tssPhysAddr, PageBytes, false);
         /* IST */
-        pt->map(ISTVirtAddr, ISTPhysAddr, PageBytes, false);
+        pTable->map(ISTVirtAddr, istPhysAddr, PageBytes, false);
         /* PF handler */
-        pt->map(PFHandlerVirtAddr, PFHandlerPhysAddr, PageBytes, false);
+        pTable->map(PFHandlerVirtAddr, pfHandlerPhysAddr, PageBytes, false);
         /* MMIO region for m5ops */
-        pt->map(MMIORegionVirtAddr, MMIORegionPhysAddr, 16*PageBytes, false);
+        pTable->map(MMIORegionVirtAddr, MMIORegionPhysAddr,
+                    16 * PageBytes, false);
     } else {
         for (int i = 0; i < contextIds.size(); i++) {
             ThreadContext * tc = system->getThreadContext(contextIds[i]);
@@ -566,7 +567,7 @@ X86_64Process::initState()
             dataAttr.expandDown = 0;
             dataAttr.system = 1;
 
-            //Initialize the segment registers.
+            // Initialize the segment registers.
             for (int seg = 0; seg < NUM_SEGMENTREGS; seg++) {
                 tc->setMiscRegNoEffect(MISCREG_SEG_BASE(seg), 0);
                 tc->setMiscRegNoEffect(MISCREG_SEG_EFF_BASE(seg), 0);
@@ -598,7 +599,7 @@ X86_64Process::initState()
             efer.ffxsr = 1; // Turn on fast fxsave and fxrstor.
             tc->setMiscReg(MISCREG_EFER, efer);
 
-            //Set up the registers that describe the operating mode.
+            // Set up the registers that describe the operating mode.
             CR0 cr0 = 0;
             cr0.pg = 1; // Turn on paging.
             cr0.cd = 0; // Don't disable caching.
@@ -677,7 +678,7 @@ I386Process::initState()
         dataAttr.expandDown = 0;
         dataAttr.system = 1;
 
-        //Initialize the segment registers.
+        // Initialize the segment registers.
         for (int seg = 0; seg < NUM_SEGMENTREGS; seg++) {
             tc->setMiscRegNoEffect(MISCREG_SEG_BASE(seg), 0);
             tc->setMiscRegNoEffect(MISCREG_SEG_EFF_BASE(seg), 0);
@@ -718,7 +719,7 @@ I386Process::initState()
         efer.ffxsr = 1; // Turn on fast fxsave and fxrstor.
         tc->setMiscReg(MISCREG_EFER, efer);
 
-        //Set up the registers that describe the operating mode.
+        // Set up the registers that describe the operating mode.
         CR0 cr0 = 0;
         cr0.pg = 1; // Turn on paging.
         cr0.cd = 0; // Don't disable caching.
@@ -746,8 +747,7 @@ X86Process::argsInit(int pageSize,
 {
     int intSize = sizeof(IntType);
 
-    typedef AuxVector<IntType> auxv_t;
-    std::vector<auxv_t> auxv = extraAuxvs;
+    std::vector<AuxVector<IntType>> auxv = extraAuxvs;
 
     string filename;
     if (argv.size() < 1)
@@ -755,15 +755,9 @@ X86Process::argsInit(int pageSize,
     else
         filename = argv[0];
 
-    //We want 16 byte alignment
+    // We want 16 byte alignment
     uint64_t align = 16;
 
-    // Patch the ld_bias for dynamic executables.
-    updateBias();
-
-    // load object file into target memory
-    objFile->loadSections(initVirtMem);
-
     enum X86CpuFeature {
         X86_OnboardFPU = 1 << 0,
         X86_VirtualModeExtensions = 1 << 1,
@@ -841,51 +835,51 @@ X86Process::argsInit(int pageSize,
 //            X86_IA64Processor |
             0;
 
-        //Bits which describe the system hardware capabilities
-        //XXX Figure out what these should be
-        auxv.push_back(auxv_t(M5_AT_HWCAP, features));
-        //The system page size
-        auxv.push_back(auxv_t(M5_AT_PAGESZ, X86ISA::PageBytes));
-        //Frequency at which times() increments
-        //Defined to be 100 in the kernel source.
-        auxv.push_back(auxv_t(M5_AT_CLKTCK, 100));
+        // Bits which describe the system hardware capabilities
+        // XXX Figure out what these should be
+        auxv.emplace_back(M5_AT_HWCAP, features);
+        // The system page size
+        auxv.emplace_back(M5_AT_PAGESZ, X86ISA::PageBytes);
+        // Frequency at which times() increments
+        // Defined to be 100 in the kernel source.
+        auxv.emplace_back(M5_AT_CLKTCK, 100);
         // This is the virtual address of the program header tables if they
         // appear in the executable image.
-        auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable()));
+        auxv.emplace_back(M5_AT_PHDR, elfObject->programHeaderTable());
         // This is the size of a program header entry from the elf file.
-        auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize()));
+        auxv.emplace_back(M5_AT_PHENT, elfObject->programHeaderSize());
         // This is the number of program headers from the original elf file.
-        auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount()));
+        auxv.emplace_back(M5_AT_PHNUM, elfObject->programHeaderCount());
         // This is the base address of the ELF interpreter; it should be
         // zero for static executables or contain the base address for
         // dynamic executables.
-        auxv.push_back(auxv_t(M5_AT_BASE, getBias()));
-        //XXX Figure out what this should be.
-        auxv.push_back(auxv_t(M5_AT_FLAGS, 0));
-        //The entry point to the program
-        auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint()));
-        //Different user and group IDs
-        auxv.push_back(auxv_t(M5_AT_UID, uid()));
-        auxv.push_back(auxv_t(M5_AT_EUID, euid()));
-        auxv.push_back(auxv_t(M5_AT_GID, gid()));
-        auxv.push_back(auxv_t(M5_AT_EGID, egid()));
-        //Whether to enable "secure mode" in the executable
-        auxv.push_back(auxv_t(M5_AT_SECURE, 0));
-        //The address of 16 "random" bytes.
-        auxv.push_back(auxv_t(M5_AT_RANDOM, 0));
-        //The name of the program
-        auxv.push_back(auxv_t(M5_AT_EXECFN, 0));
-        //The platform string
-        auxv.push_back(auxv_t(M5_AT_PLATFORM, 0));
+        auxv.emplace_back(M5_AT_BASE, getBias());
+        // XXX Figure out what this should be.
+        auxv.emplace_back(M5_AT_FLAGS, 0);
+        // The entry point to the program
+        auxv.emplace_back(M5_AT_ENTRY, objFile->entryPoint());
+        // Different user and group IDs
+        auxv.emplace_back(M5_AT_UID, uid());
+        auxv.emplace_back(M5_AT_EUID, euid());
+        auxv.emplace_back(M5_AT_GID, gid());
+        auxv.emplace_back(M5_AT_EGID, egid());
+        // Whether to enable "secure mode" in the executable
+        auxv.emplace_back(M5_AT_SECURE, 0);
+        // The address of 16 "random" bytes.
+        auxv.emplace_back(M5_AT_RANDOM, 0);
+        // The name of the program
+        auxv.emplace_back(M5_AT_EXECFN, 0);
+        // The platform string
+        auxv.emplace_back(M5_AT_PLATFORM, 0);
     }
 
-    //Figure out how big the initial stack needs to be
+    // Figure out how big the initial stack needs to be
 
     // A sentry NULL void pointer at the top of the stack.
     int sentry_size = intSize;
 
-    //This is the name of the file which is present on the initial stack
-    //It's purpose is to let the user space linker examine the original file.
+    // This is the name of the file which is present on the initial stack
+    // It's purpose is to let the user space linker examine the original file.
     int file_name_size = filename.size() + 1;
 
     const int numRandomBytes = 16;
@@ -901,10 +895,10 @@ X86Process::argsInit(int pageSize,
     for (int i = 0; i < argv.size(); ++i)
         arg_data_size += argv[i].size() + 1;
 
-    //The info_block needs to be padded so it's size is a multiple of the
-    //alignment mask. Also, it appears that there needs to be at least some
-    //padding, so if the size is already a multiple, we need to increase it
-    //anyway.
+    // The info_block needs to be padded so its size is a multiple of the
+    // alignment mask. Also, it appears that there needs to be at least some
+    // padding, so if the size is already a multiple, we need to increase it
+    // anyway.
     int base_info_block_size =
         sentry_size + file_name_size + env_data_size + arg_data_size;
 
@@ -912,7 +906,7 @@ X86Process::argsInit(int pageSize,
 
     int info_block_padding = info_block_size - base_info_block_size;
 
-    //Each auxilliary vector is two 8 byte words
+    // Each auxiliary vector is two 8 byte words
     int aux_array_size = intSize * 2 * (auxv.size() + 1);
 
     int envp_array_size = intSize * (envp.size() + 1);
@@ -920,15 +914,15 @@ X86Process::argsInit(int pageSize,
 
     int argc_size = intSize;
 
-    //Figure out the size of the contents of the actual initial frame
+    // Figure out the size of the contents of the actual initial frame
     int frame_size =
         aux_array_size +
         envp_array_size +
         argv_array_size +
         argc_size;
 
-    //There needs to be padding after the auxiliary vector data so that the
-    //very bottom of the stack is aligned properly.
+    // There needs to be padding after the auxiliary vector data so that the
+    // very bottom of the stack is aligned properly.
     int partial_size = frame_size + aux_data_size;
     int aligned_partial_size = roundUp(partial_size, align);
     int aux_padding = aligned_partial_size - partial_size;
@@ -980,54 +974,53 @@ X86Process::argsInit(int pageSize,
 
     // figure out argc
     IntType argc = argv.size();
-    IntType guestArgc = X86ISA::htog(argc);
+    IntType guestArgc = htole(argc);
 
-    //Write out the sentry void *
+    // Write out the sentry void *
     IntType sentry_NULL = 0;
-    initVirtMem.writeBlob(sentry_base,
-            (uint8_t*)&sentry_NULL, sentry_size);
+    initVirtMem.writeBlob(sentry_base, &sentry_NULL, sentry_size);
 
-    //Write the file name
+    // Write the file name
     initVirtMem.writeString(file_name_base, filename.c_str());
 
-    //Fix up the aux vectors which point to data
-    assert(auxv[auxv.size() - 3].a_type == M5_AT_RANDOM);
-    auxv[auxv.size() - 3].a_val = aux_data_base;
-    assert(auxv[auxv.size() - 2].a_type == M5_AT_EXECFN);
-    auxv[auxv.size() - 2].a_val = argv_array_base;
-    assert(auxv[auxv.size() - 1].a_type == M5_AT_PLATFORM);
-    auxv[auxv.size() - 1].a_val = aux_data_base + numRandomBytes;
-
-    //Copy the aux stuff
-    for (int x = 0; x < auxv.size(); x++) {
-        initVirtMem.writeBlob(auxv_array_base + x * 2 * intSize,
-                (uint8_t*)&(auxv[x].a_type), intSize);
-        initVirtMem.writeBlob(auxv_array_base + (x * 2 + 1) * intSize,
-                (uint8_t*)&(auxv[x].a_val), intSize);
+    // Fix up the aux vectors which point to data
+    assert(auxv[auxv.size() - 3].type == M5_AT_RANDOM);
+    auxv[auxv.size() - 3].val = aux_data_base;
+    assert(auxv[auxv.size() - 2].type == M5_AT_EXECFN);
+    auxv[auxv.size() - 2].val = argv_array_base;
+    assert(auxv[auxv.size() - 1].type == M5_AT_PLATFORM);
+    auxv[auxv.size() - 1].val = aux_data_base + numRandomBytes;
+
+
+    // Copy the aux stuff
+    Addr auxv_array_end = auxv_array_base;
+    for (const auto &aux: auxv) {
+        initVirtMem.write(auxv_array_end, aux, GuestByteOrder);
+        auxv_array_end += sizeof(aux);
     }
-    //Write out the terminating zeroed auxilliary vector
-    const uint64_t zero = 0;
-    initVirtMem.writeBlob(auxv_array_base + auxv.size() * 2 * intSize,
-                          (uint8_t*)&zero, intSize);
-    initVirtMem.writeBlob(auxv_array_base + (auxv.size() * 2 + 1) * intSize,
-                          (uint8_t*)&zero, intSize);
+    // Write out the terminating zeroed auxiliary vector
+    const AuxVector<uint64_t> zero(0, 0);
+    initVirtMem.write(auxv_array_end, zero);
+    auxv_array_end += sizeof(zero);
 
     initVirtMem.writeString(aux_data_base, platform.c_str());
 
-    copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
-    copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
+    copyStringArray(envp, envp_array_base, env_data_base,
+                    LittleEndianByteOrder, initVirtMem);
+    copyStringArray(argv, argv_array_base, arg_data_base,
+                    LittleEndianByteOrder, initVirtMem);
 
-    initVirtMem.writeBlob(argc_base, (uint8_t*)&guestArgc, intSize);
+    initVirtMem.writeBlob(argc_base, &guestArgc, intSize);
 
     ThreadContext *tc = system->getThreadContext(contextIds[0]);
-    //Set the stack pointer register
+    // Set the stack pointer register
     tc->setIntReg(StackPointerReg, stack_min);
 
     // There doesn't need to be any segment base added in since we're dealing
     // with the flat segmentation model.
     tc->pcState(getStartPC());
 
-    //Align the "stack_min" to a page boundary.
+    // Align the "stack_min" to a page boundary.
     memState->setStackMin(roundDown(stack_min, pageSize));
 }
 
@@ -1035,8 +1028,7 @@ void
 X86_64Process::argsInit(int pageSize)
 {
     std::vector<AuxVector<uint64_t> > extraAuxvs;
-    extraAuxvs.push_back(AuxVector<uint64_t>(M5_AT_SYSINFO_EHDR,
-                vsyscallPage.base));
+    extraAuxvs.emplace_back(M5_AT_SYSINFO_EHDR, vsyscallPage.base);
     X86Process::argsInit<uint64_t>(pageSize, extraAuxvs);
 }
 
@@ -1045,10 +1037,9 @@ I386Process::argsInit(int pageSize)
 {
     std::vector<AuxVector<uint32_t> > extraAuxvs;
     //Tell the binary where the vsyscall part of the vsyscall page is.
-    extraAuxvs.push_back(AuxVector<uint32_t>(M5_AT_SYSINFO,
-                vsyscallPage.base + vsyscallPage.vsyscallOffset));
-    extraAuxvs.push_back(AuxVector<uint32_t>(M5_AT_SYSINFO_EHDR,
-                vsyscallPage.base));
+    extraAuxvs.emplace_back(M5_AT_SYSINFO,
+            vsyscallPage.base + vsyscallPage.vsyscallOffset);
+    extraAuxvs.emplace_back(M5_AT_SYSINFO_EHDR, vsyscallPage.base);
     X86Process::argsInit<uint32_t>(pageSize, extraAuxvs);
 }
 
@@ -1058,36 +1049,29 @@ X86Process::setSyscallReturn(ThreadContext *tc, SyscallReturn retval)
     tc->setIntReg(INTREG_RAX, retval.encodedValue());
 }
 
-X86ISA::IntReg
+RegVal
 X86_64Process::getSyscallArg(ThreadContext *tc, int &i)
 {
     assert(i < NumArgumentRegs);
     return tc->readIntReg(ArgumentReg[i++]);
 }
 
-void
-X86_64Process::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val)
-{
-    assert(i < NumArgumentRegs);
-    return tc->setIntReg(ArgumentReg[i], val);
-}
-
 void
 X86_64Process::clone(ThreadContext *old_tc, ThreadContext *new_tc,
-                     Process *p, TheISA::IntReg flags)
+                     Process *p, RegVal flags)
 {
     X86Process::clone(old_tc, new_tc, p, flags);
     ((X86_64Process*)p)->vsyscallPage = vsyscallPage;
 }
 
-X86ISA::IntReg
+RegVal
 I386Process::getSyscallArg(ThreadContext *tc, int &i)
 {
     assert(i < NumArgumentRegs32);
     return tc->readIntReg(ArgumentReg32[i++]);
 }
 
-X86ISA::IntReg
+RegVal
 I386Process::getSyscallArg(ThreadContext *tc, int &i, int width)
 {
     assert(width == 32 || width == 64);
@@ -1098,16 +1082,9 @@ I386Process::getSyscallArg(ThreadContext *tc, int &i, int width)
     return retVal;
 }
 
-void
-I386Process::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val)
-{
-    assert(i < NumArgumentRegs);
-    return tc->setIntReg(ArgumentReg[i], val);
-}
-
 void
 I386Process::clone(ThreadContext *old_tc, ThreadContext *new_tc,
-                   Process *p, TheISA::IntReg flags)
+                   Process *p, RegVal flags)
 {
     X86Process::clone(old_tc, new_tc, p, flags);
     ((I386Process*)p)->vsyscallPage = vsyscallPage;