process.cc revision 4863:b6dacc9a39ff
111308Santhony.gutierrez@amd.com/*
211308Santhony.gutierrez@amd.com * Copyright (c) 2003-2006 The Regents of The University of Michigan
311308Santhony.gutierrez@amd.com * All rights reserved.
411308Santhony.gutierrez@amd.com *
511308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without
611308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are
711308Santhony.gutierrez@amd.com * met: redistributions of source code must retain the above copyright
811308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer;
911308Santhony.gutierrez@amd.com * redistributions in binary form must reproduce the above copyright
1011308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer in the
1111308Santhony.gutierrez@amd.com * documentation and/or other materials provided with the distribution;
1211308Santhony.gutierrez@amd.com * neither the name of the copyright holders nor the names of its
1311308Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from
1411308Santhony.gutierrez@amd.com * this software without specific prior written permission.
1511308Santhony.gutierrez@amd.com *
1611308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1711308Santhony.gutierrez@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1811308Santhony.gutierrez@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1911308Santhony.gutierrez@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2011308Santhony.gutierrez@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2111308Santhony.gutierrez@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2211308Santhony.gutierrez@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2311308Santhony.gutierrez@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2411308Santhony.gutierrez@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2511308Santhony.gutierrez@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2611308Santhony.gutierrez@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2711308Santhony.gutierrez@amd.com *
2811308Santhony.gutierrez@amd.com * Authors: Gabe Black
2911308Santhony.gutierrez@amd.com *          Ali Saidi
3011308Santhony.gutierrez@amd.com */
3111308Santhony.gutierrez@amd.com
3211308Santhony.gutierrez@amd.com/*
3311308Santhony.gutierrez@amd.com * Copyright (c) 2007 The Hewlett-Packard Development Company
3411308Santhony.gutierrez@amd.com * All rights reserved.
3511308Santhony.gutierrez@amd.com *
3611308Santhony.gutierrez@amd.com * Redistribution and use of this software in source and binary forms,
3711308Santhony.gutierrez@amd.com * with or without modification, are permitted provided that the
3811308Santhony.gutierrez@amd.com * following conditions are met:
3911308Santhony.gutierrez@amd.com *
4011308Santhony.gutierrez@amd.com * The software must be used only for Non-Commercial Use which means any
4111308Santhony.gutierrez@amd.com * use which is NOT directed to receiving any direct monetary
4211308Santhony.gutierrez@amd.com * compensation for, or commercial advantage from such use.  Illustrative
4311308Santhony.gutierrez@amd.com * examples of non-commercial use are academic research, personal study,
4411308Santhony.gutierrez@amd.com * teaching, education and corporate research & development.
4511308Santhony.gutierrez@amd.com * Illustrative examples of commercial use are distributing products for
4611308Santhony.gutierrez@amd.com * commercial advantage and providing services using the software for
4711308Santhony.gutierrez@amd.com * commercial advantage.
4811308Santhony.gutierrez@amd.com *
4911308Santhony.gutierrez@amd.com * If you wish to use this software or functionality therein that may be
5011308Santhony.gutierrez@amd.com * covered by patents for commercial use, please contact:
5111308Santhony.gutierrez@amd.com *     Director of Intellectual Property Licensing
5211308Santhony.gutierrez@amd.com *     Office of Strategy and Technology
5311308Santhony.gutierrez@amd.com *     Hewlett-Packard Company
5411308Santhony.gutierrez@amd.com *     1501 Page Mill Road
5511308Santhony.gutierrez@amd.com *     Palo Alto, California  94304
5611308Santhony.gutierrez@amd.com *
5711308Santhony.gutierrez@amd.com * Redistributions of source code must retain the above copyright notice,
5811308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer.  Redistributions
5911308Santhony.gutierrez@amd.com * in binary form must reproduce the above copyright notice, this list of
6011308Santhony.gutierrez@amd.com * conditions and the following disclaimer in the documentation and/or
6111308Santhony.gutierrez@amd.com * other materials provided with the distribution.  Neither the name of
6211308Santhony.gutierrez@amd.com * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
6311308Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from
6411308Santhony.gutierrez@amd.com * this software without specific prior written permission.  No right of
6511308Santhony.gutierrez@amd.com * sublicense is granted herewith.  Derivatives of the software and
6611308Santhony.gutierrez@amd.com * output created using the software may be prepared, but only for
6711308Santhony.gutierrez@amd.com * Non-Commercial Uses.  Derivatives of the software may be shared with
6811308Santhony.gutierrez@amd.com * others provided: (i) the others agree to abide by the list of
6911308Santhony.gutierrez@amd.com * conditions herein which includes the Non-Commercial Use restrictions;
7011308Santhony.gutierrez@amd.com * and (ii) such Derivatives of the software include the above copyright
7111308Santhony.gutierrez@amd.com * notice to acknowledge the contribution from this software where
7211308Santhony.gutierrez@amd.com * applicable, this list of conditions and the disclaimer below.
7311308Santhony.gutierrez@amd.com *
7411308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
7511308Santhony.gutierrez@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7611308Santhony.gutierrez@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
7711308Santhony.gutierrez@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7811308Santhony.gutierrez@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
7911308Santhony.gutierrez@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
8011308Santhony.gutierrez@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
8111308Santhony.gutierrez@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
8211308Santhony.gutierrez@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8311308Santhony.gutierrez@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
8411308Santhony.gutierrez@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8511308Santhony.gutierrez@amd.com *
8611308Santhony.gutierrez@amd.com * Authors: Gabe Black
8711308Santhony.gutierrez@amd.com */
8811308Santhony.gutierrez@amd.com
8911308Santhony.gutierrez@amd.com#include "arch/x86/isa_traits.hh"
9011308Santhony.gutierrez@amd.com#include "arch/x86/process.hh"
9111308Santhony.gutierrez@amd.com#include "arch/x86/segmentregs.hh"
9211308Santhony.gutierrez@amd.com#include "arch/x86/types.hh"
9311308Santhony.gutierrez@amd.com#include "base/loader/object_file.hh"
9411308Santhony.gutierrez@amd.com#include "base/loader/elf_object.hh"
9511308Santhony.gutierrez@amd.com#include "base/misc.hh"
9611308Santhony.gutierrez@amd.com#include "cpu/thread_context.hh"
9711308Santhony.gutierrez@amd.com#include "mem/page_table.hh"
9811308Santhony.gutierrez@amd.com#include "mem/translating_port.hh"
9911308Santhony.gutierrez@amd.com#include "sim/process_impl.hh"
10011308Santhony.gutierrez@amd.com#include "sim/system.hh"
10111308Santhony.gutierrez@amd.com
10211308Santhony.gutierrez@amd.comusing namespace std;
10311308Santhony.gutierrez@amd.comusing namespace X86ISA;
10411308Santhony.gutierrez@amd.com
10511308Santhony.gutierrez@amd.comM5_64_auxv_t::M5_64_auxv_t(int64_t type, int64_t val)
10611308Santhony.gutierrez@amd.com{
10711308Santhony.gutierrez@amd.com    a_type = TheISA::htog(type);
10811308Santhony.gutierrez@amd.com    a_val = TheISA::htog(val);
10911308Santhony.gutierrez@amd.com}
11011308Santhony.gutierrez@amd.com
11111308Santhony.gutierrez@amd.comX86LiveProcess::X86LiveProcess(const std::string &nm, ObjectFile *objFile,
11211308Santhony.gutierrez@amd.com        System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
11311308Santhony.gutierrez@amd.com        std::vector<std::string> &argv, std::vector<std::string> &envp,
11411308Santhony.gutierrez@amd.com        const std::string &cwd,
11511308Santhony.gutierrez@amd.com        uint64_t _uid, uint64_t _euid, uint64_t _gid, uint64_t _egid,
11611308Santhony.gutierrez@amd.com        uint64_t _pid, uint64_t _ppid)
11711308Santhony.gutierrez@amd.com    : LiveProcess(nm, objFile, _system, stdin_fd, stdout_fd, stderr_fd,
11811308Santhony.gutierrez@amd.com        argv, envp, cwd, _uid, _euid, _gid, _egid, _pid, _ppid)
11911308Santhony.gutierrez@amd.com{
12011308Santhony.gutierrez@amd.com    brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
12111308Santhony.gutierrez@amd.com    brk_point = roundUp(brk_point, VMPageSize);
12211308Santhony.gutierrez@amd.com
12311308Santhony.gutierrez@amd.com    // Set pointer for next thread stack.  Reserve 8M for main stack.
12411308Santhony.gutierrez@amd.com    next_thread_stack_base = stack_base - (8 * 1024 * 1024);
12511308Santhony.gutierrez@amd.com
12611308Santhony.gutierrez@amd.com    // Set up stack. On X86_64 Linux, stack goes from the top of memory
12711308Santhony.gutierrez@amd.com    // downward, less the hole for the kernel address space plus one page
12811308Santhony.gutierrez@amd.com    // for undertermined purposes.
12911308Santhony.gutierrez@amd.com    stack_base = (Addr)0x7FFFFFFFF000ULL;
13011308Santhony.gutierrez@amd.com
13111308Santhony.gutierrez@amd.com    // Set up region for mmaps. This was determined empirically and may not
13211308Santhony.gutierrez@amd.com    // always be correct.
13311308Santhony.gutierrez@amd.com    mmap_start = mmap_end = 0x2aaaaaaab000;
13411308Santhony.gutierrez@amd.com}
13511308Santhony.gutierrez@amd.com
13611308Santhony.gutierrez@amd.comvoid X86LiveProcess::handleTrap(int trapNum, ThreadContext *tc)
13711308Santhony.gutierrez@amd.com{
13811308Santhony.gutierrez@amd.com    switch(trapNum)
13911308Santhony.gutierrez@amd.com    {
14011308Santhony.gutierrez@amd.com      default:
14111308Santhony.gutierrez@amd.com        panic("Unimplemented trap to operating system: trap number %#x.\n", trapNum);
14211308Santhony.gutierrez@amd.com    }
14311308Santhony.gutierrez@amd.com}
14411308Santhony.gutierrez@amd.com
14511308Santhony.gutierrez@amd.comvoid
14611308Santhony.gutierrez@amd.comX86LiveProcess::startup()
14711308Santhony.gutierrez@amd.com{
14811308Santhony.gutierrez@amd.com    argsInit(sizeof(IntReg), VMPageSize);
14911308Santhony.gutierrez@amd.com    for(int i = 0; i < NUM_SEGMENTREGS; i++)
15011308Santhony.gutierrez@amd.com        threadContexts[0]->setMiscRegNoEffect(MISCREG_ES_BASE + i, 0);
15111308Santhony.gutierrez@amd.com}
15211308Santhony.gutierrez@amd.com
15311308Santhony.gutierrez@amd.comvoid
15411308Santhony.gutierrez@amd.comX86LiveProcess::argsInit(int intSize, int pageSize)
15511308Santhony.gutierrez@amd.com{
15611308Santhony.gutierrez@amd.com    typedef M5_64_auxv_t auxv_t;
15711308Santhony.gutierrez@amd.com    Process::startup();
15811308Santhony.gutierrez@amd.com
15911308Santhony.gutierrez@amd.com    string filename;
16011308Santhony.gutierrez@amd.com    if(argv.size() < 1)
16111308Santhony.gutierrez@amd.com        filename = "";
16211308Santhony.gutierrez@amd.com    else
16311308Santhony.gutierrez@amd.com        filename = argv[0];
16411308Santhony.gutierrez@amd.com
16511308Santhony.gutierrez@amd.com    //We want 16 byte alignment
16611308Santhony.gutierrez@amd.com    uint64_t align = 16;
16711308Santhony.gutierrez@amd.com
16811308Santhony.gutierrez@amd.com    // load object file into target memory
16911308Santhony.gutierrez@amd.com    objFile->loadSections(initVirtMem);
17011308Santhony.gutierrez@amd.com
17111308Santhony.gutierrez@amd.com    enum X86CpuFeature {
17211308Santhony.gutierrez@amd.com        X86_OnboardFPU = 1 << 0,
17311308Santhony.gutierrez@amd.com        X86_VirtualModeExtensions = 1 << 1,
17411308Santhony.gutierrez@amd.com        X86_DebuggingExtensions = 1 << 2,
17511308Santhony.gutierrez@amd.com        X86_PageSizeExtensions = 1 << 3,
17611308Santhony.gutierrez@amd.com
17711308Santhony.gutierrez@amd.com        X86_TimeStampCounter = 1 << 4,
17811308Santhony.gutierrez@amd.com        X86_ModelSpecificRegisters = 1 << 5,
17911308Santhony.gutierrez@amd.com        X86_PhysicalAddressExtensions = 1 << 6,
18011308Santhony.gutierrez@amd.com        X86_MachineCheckExtensions = 1 << 7,
18111308Santhony.gutierrez@amd.com
18211308Santhony.gutierrez@amd.com        X86_CMPXCHG8Instruction = 1 << 8,
18311308Santhony.gutierrez@amd.com        X86_OnboardAPIC = 1 << 9,
18411308Santhony.gutierrez@amd.com        X86_SYSENTER_SYSEXIT = 1 << 11,
18511308Santhony.gutierrez@amd.com
18611308Santhony.gutierrez@amd.com        X86_MemoryTypeRangeRegisters = 1 << 12,
18711308Santhony.gutierrez@amd.com        X86_PageGlobalEnable = 1 << 13,
18811308Santhony.gutierrez@amd.com        X86_MachineCheckArchitecture = 1 << 14,
18911308Santhony.gutierrez@amd.com        X86_CMOVInstruction = 1 << 15,
19011308Santhony.gutierrez@amd.com
19111308Santhony.gutierrez@amd.com        X86_PageAttributeTable = 1 << 16,
19211308Santhony.gutierrez@amd.com        X86_36BitPSEs = 1 << 17,
19311308Santhony.gutierrez@amd.com        X86_ProcessorSerialNumber = 1 << 18,
19411308Santhony.gutierrez@amd.com        X86_CLFLUSHInstruction = 1 << 19,
19511308Santhony.gutierrez@amd.com
19611308Santhony.gutierrez@amd.com        X86_DebugTraceStore = 1 << 21,
19711308Santhony.gutierrez@amd.com        X86_ACPIViaMSR = 1 << 22,
19811308Santhony.gutierrez@amd.com        X86_MultimediaExtensions = 1 << 23,
19911308Santhony.gutierrez@amd.com
20011308Santhony.gutierrez@amd.com        X86_FXSAVE_FXRSTOR = 1 << 24,
20111308Santhony.gutierrez@amd.com        X86_StreamingSIMDExtensions = 1 << 25,
20211308Santhony.gutierrez@amd.com        X86_StreamingSIMDExtensions2 = 1 << 26,
20311308Santhony.gutierrez@amd.com        X86_CPUSelfSnoop = 1 << 27,
20411308Santhony.gutierrez@amd.com
20511308Santhony.gutierrez@amd.com        X86_HyperThreading = 1 << 28,
20611308Santhony.gutierrez@amd.com        X86_AutomaticClockControl = 1 << 29,
20711308Santhony.gutierrez@amd.com        X86_IA64Processor = 1 << 30
20811308Santhony.gutierrez@amd.com    };
20911308Santhony.gutierrez@amd.com
21011308Santhony.gutierrez@amd.com    //Setup the auxilliary vectors. These will already have endian conversion.
21111308Santhony.gutierrez@amd.com    //Auxilliary vectors are loaded only for elf formatted executables.
21211308Santhony.gutierrez@amd.com    ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
21311308Santhony.gutierrez@amd.com    if(elfObject)
21411308Santhony.gutierrez@amd.com    {
21511308Santhony.gutierrez@amd.com        uint64_t features =
21611308Santhony.gutierrez@amd.com            X86_OnboardFPU |
21711308Santhony.gutierrez@amd.com            X86_VirtualModeExtensions |
21811308Santhony.gutierrez@amd.com            X86_DebuggingExtensions |
21911308Santhony.gutierrez@amd.com            X86_PageSizeExtensions |
22011308Santhony.gutierrez@amd.com            X86_TimeStampCounter |
22111308Santhony.gutierrez@amd.com            X86_ModelSpecificRegisters |
22211308Santhony.gutierrez@amd.com            X86_PhysicalAddressExtensions |
22311308Santhony.gutierrez@amd.com            X86_MachineCheckExtensions |
22411308Santhony.gutierrez@amd.com            X86_CMPXCHG8Instruction |
22511308Santhony.gutierrez@amd.com            X86_OnboardAPIC |
22611308Santhony.gutierrez@amd.com            X86_SYSENTER_SYSEXIT |
22711308Santhony.gutierrez@amd.com            X86_MemoryTypeRangeRegisters |
22811308Santhony.gutierrez@amd.com            X86_PageGlobalEnable |
22911308Santhony.gutierrez@amd.com            X86_MachineCheckArchitecture |
23011308Santhony.gutierrez@amd.com            X86_CMOVInstruction |
23111308Santhony.gutierrez@amd.com            X86_PageAttributeTable |
23211308Santhony.gutierrez@amd.com            X86_36BitPSEs |
23311308Santhony.gutierrez@amd.com//            X86_ProcessorSerialNumber |
23411308Santhony.gutierrez@amd.com            X86_CLFLUSHInstruction |
23511308Santhony.gutierrez@amd.com//            X86_DebugTraceStore |
23611308Santhony.gutierrez@amd.com//            X86_ACPIViaMSR |
23711308Santhony.gutierrez@amd.com            X86_MultimediaExtensions |
23811308Santhony.gutierrez@amd.com            X86_FXSAVE_FXRSTOR |
23911308Santhony.gutierrez@amd.com            X86_StreamingSIMDExtensions |
24011308Santhony.gutierrez@amd.com            X86_StreamingSIMDExtensions2 |
24111308Santhony.gutierrez@amd.com//            X86_CPUSelfSnoop |
24211308Santhony.gutierrez@amd.com//            X86_HyperThreading |
24311308Santhony.gutierrez@amd.com//            X86_AutomaticClockControl |
24411308Santhony.gutierrez@amd.com//            X86_IA64Processor |
24511308Santhony.gutierrez@amd.com            0;
24611308Santhony.gutierrez@amd.com
24711308Santhony.gutierrez@amd.com        //Bits which describe the system hardware capabilities
24811308Santhony.gutierrez@amd.com        //XXX Figure out what these should be
24911308Santhony.gutierrez@amd.com        auxv.push_back(auxv_t(M5_AT_HWCAP, features));
25011308Santhony.gutierrez@amd.com        //The system page size
25111308Santhony.gutierrez@amd.com        auxv.push_back(auxv_t(M5_AT_PAGESZ, X86ISA::VMPageSize));
25211308Santhony.gutierrez@amd.com        //Frequency at which times() increments
25311308Santhony.gutierrez@amd.com        auxv.push_back(auxv_t(M5_AT_CLKTCK, 100));
25411308Santhony.gutierrez@amd.com        // For statically linked executables, this is the virtual address of the
25511308Santhony.gutierrez@amd.com        // program header tables if they appear in the executable image
25611308Santhony.gutierrez@amd.com        auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable()));
25711308Santhony.gutierrez@amd.com        // This is the size of a program header entry from the elf file.
25811308Santhony.gutierrez@amd.com        auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize()));
25911308Santhony.gutierrez@amd.com        // This is the number of program headers from the original elf file.
26011308Santhony.gutierrez@amd.com        auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount()));
26111308Santhony.gutierrez@amd.com        //Defined to be 100 in the kernel source.
26211308Santhony.gutierrez@amd.com        //This is the address of the elf "interpreter", It should be set
26311308Santhony.gutierrez@amd.com        //to 0 for regular executables. It should be something else
26411308Santhony.gutierrez@amd.com        //(not sure what) for dynamic libraries.
26511308Santhony.gutierrez@amd.com        auxv.push_back(auxv_t(M5_AT_BASE, 0));
26611308Santhony.gutierrez@amd.com
26711308Santhony.gutierrez@amd.com        //XXX Figure out what this should be.
26811308Santhony.gutierrez@amd.com        auxv.push_back(auxv_t(M5_AT_FLAGS, 0));
26911308Santhony.gutierrez@amd.com        //The entry point to the program
27011308Santhony.gutierrez@amd.com        auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint()));
27111308Santhony.gutierrez@amd.com        //Different user and group IDs
27211308Santhony.gutierrez@amd.com        auxv.push_back(auxv_t(M5_AT_UID, uid()));
27311308Santhony.gutierrez@amd.com        auxv.push_back(auxv_t(M5_AT_EUID, euid()));
27411308Santhony.gutierrez@amd.com        auxv.push_back(auxv_t(M5_AT_GID, gid()));
27511308Santhony.gutierrez@amd.com        auxv.push_back(auxv_t(M5_AT_EGID, egid()));
27611308Santhony.gutierrez@amd.com        //Whether to enable "secure mode" in the executable
27711308Santhony.gutierrez@amd.com        auxv.push_back(auxv_t(M5_AT_SECURE, 0));
27811308Santhony.gutierrez@amd.com        //The string "x86_64" with unknown meaning
27911308Santhony.gutierrez@amd.com        auxv.push_back(auxv_t(M5_AT_PLATFORM, 0));
28011308Santhony.gutierrez@amd.com    }
28111308Santhony.gutierrez@amd.com
28211308Santhony.gutierrez@amd.com    //Figure out how big the initial stack needs to be
28311308Santhony.gutierrez@amd.com
28411308Santhony.gutierrez@amd.com    // A sentry NULL void pointer at the top of the stack.
28511308Santhony.gutierrez@amd.com    int sentry_size = intSize;
28611308Santhony.gutierrez@amd.com
28711308Santhony.gutierrez@amd.com    //This is the name of the file which is present on the initial stack
28811308Santhony.gutierrez@amd.com    //It's purpose is to let the user space linker examine the original file.
28911308Santhony.gutierrez@amd.com    int file_name_size = filename.size() + 1;
29011308Santhony.gutierrez@amd.com
29111308Santhony.gutierrez@amd.com    string platform = "x86_64";
29211308Santhony.gutierrez@amd.com    int aux_data_size = platform.size() + 1;
29311308Santhony.gutierrez@amd.com
29411308Santhony.gutierrez@amd.com    int env_data_size = 0;
29511308Santhony.gutierrez@amd.com    for (int i = 0; i < envp.size(); ++i) {
29611308Santhony.gutierrez@amd.com        env_data_size += envp[i].size() + 1;
29711308Santhony.gutierrez@amd.com    }
29811308Santhony.gutierrez@amd.com    int arg_data_size = 0;
29911308Santhony.gutierrez@amd.com    for (int i = 0; i < argv.size(); ++i) {
30011308Santhony.gutierrez@amd.com        arg_data_size += argv[i].size() + 1;
30111308Santhony.gutierrez@amd.com    }
30211308Santhony.gutierrez@amd.com
30311308Santhony.gutierrez@amd.com    //The info_block needs to be padded so it's size is a multiple of the
30411308Santhony.gutierrez@amd.com    //alignment mask. Also, it appears that there needs to be at least some
30511308Santhony.gutierrez@amd.com    //padding, so if the size is already a multiple, we need to increase it
30611308Santhony.gutierrez@amd.com    //anyway.
30711308Santhony.gutierrez@amd.com    int base_info_block_size =
30811308Santhony.gutierrez@amd.com        sentry_size + file_name_size + env_data_size + arg_data_size;
30911308Santhony.gutierrez@amd.com
31011308Santhony.gutierrez@amd.com    int info_block_size = roundUp(base_info_block_size, align);
31111308Santhony.gutierrez@amd.com
31211308Santhony.gutierrez@amd.com    int info_block_padding = info_block_size - base_info_block_size;
31311308Santhony.gutierrez@amd.com
31411308Santhony.gutierrez@amd.com    //Each auxilliary vector is two 8 byte words
31511308Santhony.gutierrez@amd.com    int aux_array_size = intSize * 2 * (auxv.size() + 1);
31611308Santhony.gutierrez@amd.com
31711308Santhony.gutierrez@amd.com    int envp_array_size = intSize * (envp.size() + 1);
31811308Santhony.gutierrez@amd.com    int argv_array_size = intSize * (argv.size() + 1);
31911308Santhony.gutierrez@amd.com
32011308Santhony.gutierrez@amd.com    int argc_size = intSize;
32111308Santhony.gutierrez@amd.com
32211308Santhony.gutierrez@amd.com    //Figure out the size of the contents of the actual initial frame
32311308Santhony.gutierrez@amd.com    int frame_size =
32411308Santhony.gutierrez@amd.com        aux_array_size +
32511308Santhony.gutierrez@amd.com        envp_array_size +
32611308Santhony.gutierrez@amd.com        argv_array_size +
32711308Santhony.gutierrez@amd.com        argc_size;
32811308Santhony.gutierrez@amd.com
32911308Santhony.gutierrez@amd.com    //There needs to be padding after the auxiliary vector data so that the
33011308Santhony.gutierrez@amd.com    //very bottom of the stack is aligned properly.
33111308Santhony.gutierrez@amd.com    int partial_size = frame_size + aux_data_size;
33211308Santhony.gutierrez@amd.com    int aligned_partial_size = roundUp(partial_size, align);
33311308Santhony.gutierrez@amd.com    int aux_padding = aligned_partial_size - partial_size;
33411308Santhony.gutierrez@amd.com
33511308Santhony.gutierrez@amd.com    int space_needed =
33611308Santhony.gutierrez@amd.com        info_block_size +
33711308Santhony.gutierrez@amd.com        aux_data_size +
33811308Santhony.gutierrez@amd.com        aux_padding +
33911308Santhony.gutierrez@amd.com        frame_size;
34011308Santhony.gutierrez@amd.com
34111308Santhony.gutierrez@amd.com    stack_min = stack_base - space_needed;
34211308Santhony.gutierrez@amd.com    stack_min = roundDown(stack_min, align);
34311308Santhony.gutierrez@amd.com    stack_size = stack_base - stack_min;
34411308Santhony.gutierrez@amd.com
34511308Santhony.gutierrez@amd.com    // map memory
34611308Santhony.gutierrez@amd.com    pTable->allocate(roundDown(stack_min, pageSize),
34711308Santhony.gutierrez@amd.com                     roundUp(stack_size, pageSize));
34811308Santhony.gutierrez@amd.com
34911308Santhony.gutierrez@amd.com    // map out initial stack contents
35011308Santhony.gutierrez@amd.com    Addr sentry_base = stack_base - sentry_size;
35111308Santhony.gutierrez@amd.com    Addr file_name_base = sentry_base - file_name_size;
35211308Santhony.gutierrez@amd.com    Addr env_data_base = file_name_base - env_data_size;
35311308Santhony.gutierrez@amd.com    Addr arg_data_base = env_data_base - arg_data_size;
35411308Santhony.gutierrez@amd.com    Addr aux_data_base = arg_data_base - info_block_padding - aux_data_size;
35511308Santhony.gutierrez@amd.com    Addr auxv_array_base = aux_data_base - aux_array_size - aux_padding;
35611308Santhony.gutierrez@amd.com    Addr envp_array_base = auxv_array_base - envp_array_size;
35711308Santhony.gutierrez@amd.com    Addr argv_array_base = envp_array_base - argv_array_size;
35811308Santhony.gutierrez@amd.com    Addr argc_base = argv_array_base - argc_size;
35911308Santhony.gutierrez@amd.com
36011308Santhony.gutierrez@amd.com    DPRINTF(X86, "The addresses of items on the initial stack:\n");
36111308Santhony.gutierrez@amd.com    DPRINTF(X86, "0x%x - file name\n", file_name_base);
36211308Santhony.gutierrez@amd.com    DPRINTF(X86, "0x%x - env data\n", env_data_base);
36311308Santhony.gutierrez@amd.com    DPRINTF(X86, "0x%x - arg data\n", arg_data_base);
36411308Santhony.gutierrez@amd.com    DPRINTF(X86, "0x%x - aux data\n", aux_data_base);
36511308Santhony.gutierrez@amd.com    DPRINTF(X86, "0x%x - auxv array\n", auxv_array_base);
36611308Santhony.gutierrez@amd.com    DPRINTF(X86, "0x%x - envp array\n", envp_array_base);
36711308Santhony.gutierrez@amd.com    DPRINTF(X86, "0x%x - argv array\n", argv_array_base);
36811308Santhony.gutierrez@amd.com    DPRINTF(X86, "0x%x - argc \n", argc_base);
369    DPRINTF(X86, "0x%x - stack min\n", stack_min);
370
371    // write contents to stack
372
373    // figure out argc
374    uint64_t argc = argv.size();
375    uint64_t guestArgc = TheISA::htog(argc);
376
377    //Write out the sentry void *
378    uint64_t sentry_NULL = 0;
379    initVirtMem->writeBlob(sentry_base,
380            (uint8_t*)&sentry_NULL, sentry_size);
381
382    //Write the file name
383    initVirtMem->writeString(file_name_base, filename.c_str());
384
385    //Fix up the aux vector which points to the "platform" string
386    assert(auxv[auxv.size() - 1].a_type = M5_AT_PLATFORM);
387    auxv[auxv.size() - 1].a_val = aux_data_base;
388
389    //Copy the aux stuff
390    for(int x = 0; x < auxv.size(); x++)
391    {
392        initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize,
393                (uint8_t*)&(auxv[x].a_type), intSize);
394        initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize,
395                (uint8_t*)&(auxv[x].a_val), intSize);
396    }
397    //Write out the terminating zeroed auxilliary vector
398    const uint64_t zero = 0;
399    initVirtMem->writeBlob(auxv_array_base + 2 * intSize * auxv.size(),
400            (uint8_t*)&zero, 2 * intSize);
401
402    initVirtMem->writeString(aux_data_base, platform.c_str());
403
404    copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
405    copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
406
407    initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize);
408
409    //Set the stack pointer register
410    threadContexts[0]->setIntReg(StackPointerReg, stack_min);
411
412    Addr prog_entry = objFile->entryPoint();
413    threadContexts[0]->setPC(prog_entry);
414    threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst));
415
416    //Align the "stack_min" to a page boundary.
417    stack_min = roundDown(stack_min, pageSize);
418
419//    num_processes++;
420}
421