process.cc revision 4777
14166Sgblack@eecs.umich.edu/*
210554Salexandru.dutu@amd.com * Copyright (c) 2003-2006 The Regents of The University of Michigan
37087Snate@binkert.org * All rights reserved.
47087Snate@binkert.org *
57087Snate@binkert.org * Redistribution and use in source and binary forms, with or without
67087Snate@binkert.org * modification, are permitted provided that the following conditions are
77087Snate@binkert.org * met: redistributions of source code must retain the above copyright
87087Snate@binkert.org * notice, this list of conditions and the following disclaimer;
97087Snate@binkert.org * redistributions in binary form must reproduce the above copyright
107087Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
117087Snate@binkert.org * documentation and/or other materials provided with the distribution;
127087Snate@binkert.org * neither the name of the copyright holders nor the names of its
137087Snate@binkert.org * contributors may be used to endorse or promote products derived from
147087Snate@binkert.org * this software without specific prior written permission.
154166Sgblack@eecs.umich.edu *
164166Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
174166Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
184166Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
194166Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
204166Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
214166Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
224166Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
234166Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
244166Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
254166Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
264166Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
274166Sgblack@eecs.umich.edu *
284166Sgblack@eecs.umich.edu * Authors: Gabe Black
294166Sgblack@eecs.umich.edu *          Ali Saidi
304166Sgblack@eecs.umich.edu */
314166Sgblack@eecs.umich.edu
324166Sgblack@eecs.umich.edu/*
334166Sgblack@eecs.umich.edu * Copyright (c) 2007 The Hewlett-Packard Development Company
344166Sgblack@eecs.umich.edu * All rights reserved.
354166Sgblack@eecs.umich.edu *
364166Sgblack@eecs.umich.edu * Redistribution and use of this software in source and binary forms,
374166Sgblack@eecs.umich.edu * with or without modification, are permitted provided that the
384166Sgblack@eecs.umich.edu * following conditions are met:
394166Sgblack@eecs.umich.edu *
404166Sgblack@eecs.umich.edu * The software must be used only for Non-Commercial Use which means any
414166Sgblack@eecs.umich.edu * use which is NOT directed to receiving any direct monetary
424166Sgblack@eecs.umich.edu * compensation for, or commercial advantage from such use.  Illustrative
434166Sgblack@eecs.umich.edu * examples of non-commercial use are academic research, personal study,
444166Sgblack@eecs.umich.edu * teaching, education and corporate research & development.
4511793Sbrandon.potter@amd.com * Illustrative examples of commercial use are distributing products for
4611793Sbrandon.potter@amd.com * commercial advantage and providing services using the software for
4711854Sbrandon.potter@amd.com * commercial advantage.
4811854Sbrandon.potter@amd.com *
4911854Sbrandon.potter@amd.com * If you wish to use this software or functionality therein that may be
5011793Sbrandon.potter@amd.com * covered by patents for commercial use, please contact:
518229Snate@binkert.org *     Director of Intellectual Property Licensing
528229Snate@binkert.org *     Office of Strategy and Technology
5310554Salexandru.dutu@amd.com *     Hewlett-Packard Company
544166Sgblack@eecs.umich.edu *     1501 Page Mill Road
558229Snate@binkert.org *     Palo Alto, California  94304
564166Sgblack@eecs.umich.edu *
5712334Sgabeblack@google.com * Redistributions of source code must retain the above copyright notice,
585004Sgblack@eecs.umich.edu * this list of conditions and the following disclaimer.  Redistributions
594166Sgblack@eecs.umich.edu * in binary form must reproduce the above copyright notice, this list of
608232Snate@binkert.org * conditions and the following disclaimer in the documentation and/or
6110554Salexandru.dutu@amd.com * other materials provided with the distribution.  Neither the name of
624166Sgblack@eecs.umich.edu * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
6312431Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
6411854Sbrandon.potter@amd.com * this software without specific prior written permission.  No right of
654434Ssaidi@eecs.umich.edu * sublicense is granted herewith.  Derivatives of the software and
6611794Sbrandon.potter@amd.com * output created using the software may be prepared, but only for
6711800Sbrandon.potter@amd.com * Non-Commercial Uses.  Derivatives of the software may be shared with
684166Sgblack@eecs.umich.edu * others provided: (i) the others agree to abide by the list of
694166Sgblack@eecs.umich.edu * conditions herein which includes the Non-Commercial Use restrictions;
704166Sgblack@eecs.umich.edu * and (ii) such Derivatives of the software include the above copyright
714166Sgblack@eecs.umich.edu * notice to acknowledge the contribution from this software where
724166Sgblack@eecs.umich.edu * applicable, this list of conditions and the disclaimer below.
735958Sgblack@eecs.umich.edu *
745958Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
755958Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
765958Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
7711906SBrandon.Potter@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
785958Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
7911906SBrandon.Potter@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
805958Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
815958Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
825958Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8311704Santhony.gutierrez@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
8411704Santhony.gutierrez@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8511704Santhony.gutierrez@amd.com *
8611704Santhony.gutierrez@amd.com * Authors: Gabe Black
875959Sgblack@eecs.umich.edu */
885959Sgblack@eecs.umich.edu
895959Sgblack@eecs.umich.edu#include "arch/x86/isa_traits.hh"
905959Sgblack@eecs.umich.edu#include "arch/x86/process.hh"
915959Sgblack@eecs.umich.edu#include "arch/x86/types.hh"
925959Sgblack@eecs.umich.edu#include "base/loader/object_file.hh"
9311385Sbrandon.potter@amd.com#include "base/loader/elf_object.hh"
945959Sgblack@eecs.umich.edu#include "base/misc.hh"
9511704Santhony.gutierrez@amd.com#include "cpu/thread_context.hh"
9611704Santhony.gutierrez@amd.com#include "mem/page_table.hh"
9711704Santhony.gutierrez@amd.com#include "mem/translating_port.hh"
984166Sgblack@eecs.umich.edu#include "sim/process_impl.hh"
9912460Sgabeblack@google.com#include "sim/system.hh"
10012460Sgabeblack@google.com
10112460Sgabeblack@google.comusing namespace std;
10212460Sgabeblack@google.comusing namespace X86ISA;
10312460Sgabeblack@google.com
10412460Sgabeblack@google.comM5_64_auxv_t::M5_64_auxv_t(int64_t type, int64_t val)
10512460Sgabeblack@google.com{
10612460Sgabeblack@google.com    a_type = TheISA::htog(type);
10712460Sgabeblack@google.com    a_val = TheISA::htog(val);
10812431Sgabeblack@google.com}
10911851Sbrandon.potter@amd.com
11012431Sgabeblack@google.comX86LiveProcess::X86LiveProcess(const std::string &nm, ObjectFile *objFile,
11112448Sgabeblack@google.com        System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
11212460Sgabeblack@google.com        std::vector<std::string> &argv, std::vector<std::string> &envp,
11312460Sgabeblack@google.com        const std::string &cwd,
11412448Sgabeblack@google.com        uint64_t _uid, uint64_t _euid, uint64_t _gid, uint64_t _egid,
11512448Sgabeblack@google.com        uint64_t _pid, uint64_t _ppid)
11612431Sgabeblack@google.com    : LiveProcess(nm, objFile, _system, stdin_fd, stdout_fd, stderr_fd,
11712431Sgabeblack@google.com        argv, envp, cwd, _uid, _euid, _gid, _egid, _pid, _ppid)
1184166Sgblack@eecs.umich.edu{
11911886Sbrandon.potter@amd.com    brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
12011886Sbrandon.potter@amd.com    brk_point = roundUp(brk_point, VMPageSize);
12111886Sbrandon.potter@amd.com
12213613Sgabeblack@google.com    // Set pointer for next thread stack.  Reserve 8M for main stack.
12311886Sbrandon.potter@amd.com    next_thread_stack_base = stack_base - (8 * 1024 * 1024);
12411886Sbrandon.potter@amd.com
12511886Sbrandon.potter@amd.com    // Set up stack. On SPARC Linux, stack goes from the top of memory
12611886Sbrandon.potter@amd.com    // downward, less the hole for the kernel address space.
1275956Sgblack@eecs.umich.edu    stack_base = (Addr)0x80000000000ULL;
1284166Sgblack@eecs.umich.edu
12911851Sbrandon.potter@amd.com    // Set up region for mmaps.  Tru64 seems to start just above 0 and
13011851Sbrandon.potter@amd.com    // grow up from there.
13111851Sbrandon.potter@amd.com    mmap_start = mmap_end = 0xfffff80000000000ULL;
1325956Sgblack@eecs.umich.edu}
1336709Svince@csl.cornell.edu
1346709Svince@csl.cornell.eduvoid X86LiveProcess::handleTrap(int trapNum, ThreadContext *tc)
13510318Sandreas.hansson@arm.com{
1366709Svince@csl.cornell.edu    switch(trapNum)
1379679Smjleven@sandia.gov    {
1386709Svince@csl.cornell.edu      default:
13911905SBrandon.Potter@amd.com        panic("Unimplemented trap to operating system: trap number %#x.\n", trapNum);
14011905SBrandon.Potter@amd.com    }
14111905SBrandon.Potter@amd.com}
14211905SBrandon.Potter@amd.com
14311905SBrandon.Potter@amd.comvoid
14411905SBrandon.Potter@amd.comX86LiveProcess::startup()
1454166Sgblack@eecs.umich.edu{
14611905SBrandon.Potter@amd.com    argsInit(sizeof(IntReg), VMPageSize);
14711905SBrandon.Potter@amd.com
1484166Sgblack@eecs.umich.edu    //The AMD64 abi says that only rsp and rdx are defined at process
1494166Sgblack@eecs.umich.edu    //startup. rsp will be set by argsInit, and I don't understand what
1505973Sgblack@eecs.umich.edu    //rdx should be set to. The other floating point and integer registers
15111877Sbrandon.potter@amd.com    //will be zeroed by the register file constructors, but control registers
1525973Sgblack@eecs.umich.edu    //should be initialized here. Since none of those are implemented, there
15313915Sgabeblack@google.com    //isn't anything here.
1547720Sgblack@eecs.umich.edu}
1555973Sgblack@eecs.umich.edu
1565973Sgblack@eecs.umich.eduvoid
1577720Sgblack@eecs.umich.eduX86LiveProcess::argsInit(int intSize, int pageSize)
1587720Sgblack@eecs.umich.edu{
1595973Sgblack@eecs.umich.edu    typedef M5_64_auxv_t auxv_t;
16011877Sbrandon.potter@amd.com    Process::startup();
1615973Sgblack@eecs.umich.edu
1625973Sgblack@eecs.umich.edu    string filename;
1635973Sgblack@eecs.umich.edu    if(argv.size() < 1)
16411851Sbrandon.potter@amd.com        filename = "";
16511851Sbrandon.potter@amd.com    else
16611851Sbrandon.potter@amd.com        filename = argv[0];
1674166Sgblack@eecs.umich.edu
16813867Salexandru.dutu@amd.com    Addr alignmentMask = ~(intSize - 1);
16913867Salexandru.dutu@amd.com
17013867Salexandru.dutu@amd.com    // load object file into target memory
1719026Sgblack@eecs.umich.edu    objFile->loadSections(initVirtMem);
17210318Sandreas.hansson@arm.com
1735973Sgblack@eecs.umich.edu    //These are the auxilliary vector types
1745973Sgblack@eecs.umich.edu    enum auxTypes
17510318Sandreas.hansson@arm.com    {
1765973Sgblack@eecs.umich.edu        X86_AT_NULL = 0,
1775973Sgblack@eecs.umich.edu        X86_AT_IGNORE = 1,
1785973Sgblack@eecs.umich.edu        X86_AT_EXECFD = 2,
17911905SBrandon.Potter@amd.com        X86_AT_PHDR = 3,
18011905SBrandon.Potter@amd.com        X86_AT_PHENT = 4,
18111905SBrandon.Potter@amd.com        X86_AT_PHNUM = 5,
18211905SBrandon.Potter@amd.com        X86_AT_PAGESZ = 6,
18311905SBrandon.Potter@amd.com        X86_AT_BASE = 7,
18411905SBrandon.Potter@amd.com        X86_AT_FLAGS = 8,
1855956Sgblack@eecs.umich.edu        X86_AT_ENTRY = 9,
18611905SBrandon.Potter@amd.com        X86_AT_NOTELF = 10,
18711905SBrandon.Potter@amd.com        X86_AT_UID = 11,
1885956Sgblack@eecs.umich.edu        X86_AT_EUID = 12,
1895956Sgblack@eecs.umich.edu        X86_AT_GID = 13,
1905956Sgblack@eecs.umich.edu        X86_AT_EGID = 14,
19111851Sbrandon.potter@amd.com        X86_AT_PLATFORM = 15,
1925956Sgblack@eecs.umich.edu        X86_AT_HWCAP = 16,
1935956Sgblack@eecs.umich.edu        X86_AT_CLKTCK = 17,
1945956Sgblack@eecs.umich.edu
1955956Sgblack@eecs.umich.edu        X86_AT_SECURE = 13,
1964166Sgblack@eecs.umich.edu
1974166Sgblack@eecs.umich.edu        X86_AT_VECTOR_SIZE = 44
1984166Sgblack@eecs.umich.edu    };
19911851Sbrandon.potter@amd.com
2004166Sgblack@eecs.umich.edu    //Setup the auxilliary vectors. These will already have endian conversion.
20111851Sbrandon.potter@amd.com    //Auxilliary vectors are loaded only for elf formatted executables.
2025183Ssaidi@eecs.umich.edu    ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
20313867Salexandru.dutu@amd.com    if(elfObject)
20413867Salexandru.dutu@amd.com    {
20513867Salexandru.dutu@amd.com        //Bits which describe the system hardware capabilities
20611884Sbrandon.potter@amd.com        //XXX Figure out what these should be
2075140Sgblack@eecs.umich.edu        auxv.push_back(auxv_t(X86_AT_HWCAP, 0));
20811906SBrandon.Potter@amd.com        //The system page size
2098601Ssteve.reinhardt@amd.com        auxv.push_back(auxv_t(X86_AT_PAGESZ, X86ISA::VMPageSize));
2106709Svince@csl.cornell.edu        //Frequency at which times() increments
2116709Svince@csl.cornell.edu        auxv.push_back(auxv_t(X86_AT_CLKTCK, 100));
2126709Svince@csl.cornell.edu        // For statically linked executables, this is the virtual address of the
2136709Svince@csl.cornell.edu        // program header tables if they appear in the executable image
2146709Svince@csl.cornell.edu        auxv.push_back(auxv_t(X86_AT_PHDR, elfObject->programHeaderTable()));
2158852Sandreas.hansson@arm.com        // This is the size of a program header entry from the elf file.
2166709Svince@csl.cornell.edu        auxv.push_back(auxv_t(X86_AT_PHENT, elfObject->programHeaderSize()));
2176709Svince@csl.cornell.edu        // This is the number of program headers from the original elf file.
2186709Svince@csl.cornell.edu        auxv.push_back(auxv_t(X86_AT_PHNUM, elfObject->programHeaderCount()));
2196709Svince@csl.cornell.edu        //Defined to be 100 in the kernel source.
2206709Svince@csl.cornell.edu        //This is the address of the elf "interpreter", It should be set
2216709Svince@csl.cornell.edu        //to 0 for regular executables. It should be something else
2226709Svince@csl.cornell.edu        //(not sure what) for dynamic libraries.
2238852Sandreas.hansson@arm.com        auxv.push_back(auxv_t(X86_AT_BASE, 0));
2246709Svince@csl.cornell.edu
2256709Svince@csl.cornell.edu        //XXX Figure out what this should be.
22610554Salexandru.dutu@amd.com        auxv.push_back(auxv_t(X86_AT_FLAGS, 0));
22710554Salexandru.dutu@amd.com        //The entry point to the program
2285140Sgblack@eecs.umich.edu        auxv.push_back(auxv_t(X86_AT_ENTRY, objFile->entryPoint()));
22912458Sgabeblack@google.com        //Different user and group IDs
23012458Sgabeblack@google.com        auxv.push_back(auxv_t(X86_AT_UID, uid()));
23112458Sgabeblack@google.com        auxv.push_back(auxv_t(X86_AT_EUID, euid()));
23212458Sgabeblack@google.com        auxv.push_back(auxv_t(X86_AT_GID, gid()));
23312458Sgabeblack@google.com        auxv.push_back(auxv_t(X86_AT_EGID, egid()));
23412458Sgabeblack@google.com        //Whether to enable "secure mode" in the executable
23512458Sgabeblack@google.com        auxv.push_back(auxv_t(X86_AT_SECURE, 0));
23610554Salexandru.dutu@amd.com        //The string "x86_64" with unknown meaning
23710554Salexandru.dutu@amd.com        auxv.push_back(auxv_t(X86_AT_PLATFORM, 0));
23810554Salexandru.dutu@amd.com    }
23910554Salexandru.dutu@amd.com
24010554Salexandru.dutu@amd.com    //Figure out how big the initial stack needs to be
24112458Sgabeblack@google.com
24214010Sgabeblack@google.com    // The unaccounted for 0 at the top of the stack
24310554Salexandru.dutu@amd.com    int mysterious_size = intSize;
2445140Sgblack@eecs.umich.edu
24510554Salexandru.dutu@amd.com    //This is the name of the file which is present on the initial stack
24610554Salexandru.dutu@amd.com    //It's purpose is to let the user space linker examine the original file.
24710554Salexandru.dutu@amd.com    int file_name_size = filename.size() + 1;
24810554Salexandru.dutu@amd.com
24910554Salexandru.dutu@amd.com    int env_data_size = 0;
25010554Salexandru.dutu@amd.com    for (int i = 0; i < envp.size(); ++i) {
25110554Salexandru.dutu@amd.com        env_data_size += envp[i].size() + 1;
25210554Salexandru.dutu@amd.com    }
25310554Salexandru.dutu@amd.com    int arg_data_size = 0;
25412588Sgabeblack@google.com    for (int i = 0; i < argv.size(); ++i) {
25512588Sgabeblack@google.com        arg_data_size += argv[i].size() + 1;
25610554Salexandru.dutu@amd.com    }
25710554Salexandru.dutu@amd.com
25810554Salexandru.dutu@amd.com    //The info_block needs to be padded so it's size is a multiple of the
25910554Salexandru.dutu@amd.com    //alignment mask. Also, it appears that there needs to be at least some
26010554Salexandru.dutu@amd.com    //padding, so if the size is already a multiple, we need to increase it
26110554Salexandru.dutu@amd.com    //anyway.
26212458Sgabeblack@google.com    int info_block_size =
26314010Sgabeblack@google.com        (file_name_size +
26410554Salexandru.dutu@amd.com        env_data_size +
26510554Salexandru.dutu@amd.com        arg_data_size +
26610554Salexandru.dutu@amd.com        intSize) & alignmentMask;
26710554Salexandru.dutu@amd.com
26810554Salexandru.dutu@amd.com    int info_block_padding =
26910554Salexandru.dutu@amd.com        info_block_size -
27010554Salexandru.dutu@amd.com        file_name_size -
27110554Salexandru.dutu@amd.com        env_data_size -
27210554Salexandru.dutu@amd.com        arg_data_size;
27310554Salexandru.dutu@amd.com
27410554Salexandru.dutu@amd.com    //Each auxilliary vector is two 8 byte words
27510554Salexandru.dutu@amd.com    int aux_array_size = intSize * 2 * (auxv.size() + 1);
27612458Sgabeblack@google.com
27714010Sgabeblack@google.com    int envp_array_size = intSize * (envp.size() + 1);
27810554Salexandru.dutu@amd.com    int argv_array_size = intSize * (argv.size() + 1);
27910554Salexandru.dutu@amd.com
28010554Salexandru.dutu@amd.com    int argc_size = intSize;
28110554Salexandru.dutu@amd.com
28210554Salexandru.dutu@amd.com    int space_needed =
28310554Salexandru.dutu@amd.com        mysterious_size +
28410554Salexandru.dutu@amd.com        info_block_size +
28510554Salexandru.dutu@amd.com        aux_array_size +
28610554Salexandru.dutu@amd.com        envp_array_size +
28710554Salexandru.dutu@amd.com        argv_array_size +
28810554Salexandru.dutu@amd.com        argc_size;
28910554Salexandru.dutu@amd.com
29012458Sgabeblack@google.com    stack_min = stack_base - space_needed;
29114010Sgabeblack@google.com    stack_min &= alignmentMask;
29210554Salexandru.dutu@amd.com    stack_size = stack_base - stack_min;
29310554Salexandru.dutu@amd.com
29410554Salexandru.dutu@amd.com    // map memory
29510554Salexandru.dutu@amd.com    pTable->allocate(roundDown(stack_min, pageSize),
29610554Salexandru.dutu@amd.com                     roundUp(stack_size, pageSize));
29710554Salexandru.dutu@amd.com
29810554Salexandru.dutu@amd.com    // map out initial stack contents
29910554Salexandru.dutu@amd.com    Addr mysterious_base = stack_base - mysterious_size;
30010554Salexandru.dutu@amd.com    Addr file_name_base = mysterious_base - file_name_size;
30110554Salexandru.dutu@amd.com    Addr env_data_base = file_name_base - env_data_size;
30210554Salexandru.dutu@amd.com    Addr arg_data_base = env_data_base - arg_data_size;
30310554Salexandru.dutu@amd.com    Addr auxv_array_base = arg_data_base - aux_array_size - info_block_padding;
30412458Sgabeblack@google.com    Addr envp_array_base = auxv_array_base - envp_array_size;
30514010Sgabeblack@google.com    Addr argv_array_base = envp_array_base - argv_array_size;
30610554Salexandru.dutu@amd.com    Addr argc_base = argv_array_base - argc_size;
30710554Salexandru.dutu@amd.com
30810554Salexandru.dutu@amd.com    DPRINTF(X86, "The addresses of items on the initial stack:\n");
30910554Salexandru.dutu@amd.com    DPRINTF(X86, "0x%x - file name\n", file_name_base);
31010554Salexandru.dutu@amd.com    DPRINTF(X86, "0x%x - env data\n", env_data_base);
31110554Salexandru.dutu@amd.com    DPRINTF(X86, "0x%x - arg data\n", arg_data_base);
31210554Salexandru.dutu@amd.com    DPRINTF(X86, "0x%x - auxv array\n", auxv_array_base);
31310554Salexandru.dutu@amd.com    DPRINTF(X86, "0x%x - envp array\n", envp_array_base);
31410554Salexandru.dutu@amd.com    DPRINTF(X86, "0x%x - argv array\n", argv_array_base);
31510554Salexandru.dutu@amd.com    DPRINTF(X86, "0x%x - argc \n", argc_base);
31610554Salexandru.dutu@amd.com    DPRINTF(X86, "0x%x - stack min\n", stack_min);
31710554Salexandru.dutu@amd.com
31810554Salexandru.dutu@amd.com    // write contents to stack
31910554Salexandru.dutu@amd.com
32010554Salexandru.dutu@amd.com    // figure out argc
32110554Salexandru.dutu@amd.com    uint64_t argc = argv.size();
32210554Salexandru.dutu@amd.com    uint64_t guestArgc = TheISA::htog(argc);
32310554Salexandru.dutu@amd.com
32410554Salexandru.dutu@amd.com    //Write out the mysterious 0
32510554Salexandru.dutu@amd.com    uint64_t mysterious_zero = 0;
32612588Sgabeblack@google.com    initVirtMem->writeBlob(mysterious_base,
32712588Sgabeblack@google.com            (uint8_t*)&mysterious_zero, mysterious_size);
32810554Salexandru.dutu@amd.com
32910554Salexandru.dutu@amd.com    //Write the file name
33010590Sgabeblack@google.com    initVirtMem->writeString(file_name_base, filename.c_str());
33110554Salexandru.dutu@amd.com
33210554Salexandru.dutu@amd.com    //Copy the aux stuff
33310554Salexandru.dutu@amd.com    for(int x = 0; x < auxv.size(); x++)
33410554Salexandru.dutu@amd.com    {
33510554Salexandru.dutu@amd.com        initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize,
33610554Salexandru.dutu@amd.com                (uint8_t*)&(auxv[x].a_type), intSize);
33712458Sgabeblack@google.com        initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize,
33814010Sgabeblack@google.com                (uint8_t*)&(auxv[x].a_val), intSize);
33910554Salexandru.dutu@amd.com    }
34010554Salexandru.dutu@amd.com    //Write out the terminating zeroed auxilliary vector
34110554Salexandru.dutu@amd.com    const uint64_t zero = 0;
34210554Salexandru.dutu@amd.com    initVirtMem->writeBlob(auxv_array_base + 2 * intSize * auxv.size(),
34310554Salexandru.dutu@amd.com            (uint8_t*)&zero, 2 * intSize);
34410554Salexandru.dutu@amd.com
34512588Sgabeblack@google.com    copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
34612588Sgabeblack@google.com    copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
34710554Salexandru.dutu@amd.com
34810554Salexandru.dutu@amd.com    initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize);
34910554Salexandru.dutu@amd.com
35010554Salexandru.dutu@amd.com    //Set up the thread context to start running the process
35110554Salexandru.dutu@amd.com    threadContexts[0]->setIntReg(StackPointerReg, stack_min);
35210554Salexandru.dutu@amd.com
35310554Salexandru.dutu@amd.com    Addr prog_entry = objFile->entryPoint();
35410554Salexandru.dutu@amd.com    threadContexts[0]->setPC(prog_entry);
35510554Salexandru.dutu@amd.com    threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst));
35610554Salexandru.dutu@amd.com
35710554Salexandru.dutu@amd.com    //Align the "stack_min" to a page boundary.
35810554Salexandru.dutu@amd.com    stack_min = roundDown(stack_min, pageSize);
35910590Sgabeblack@google.com
36010590Sgabeblack@google.com//    num_processes++;
36110590Sgabeblack@google.com}
36210590Sgabeblack@google.com