process.cc revision 6019
111507SCurtis.Dunham@arm.com/* 211507SCurtis.Dunham@arm.com * Copyright (c) 2007-2008 The Florida State University 311960Sgabeblack@google.com * All rights reserved. 411960Sgabeblack@google.com * 511960Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 611960Sgabeblack@google.com * modification, are permitted provided that the following conditions are 711960Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 811960Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 911960Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1011960Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1111960Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1211960Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1311960Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1411960Sgabeblack@google.com * this software without specific prior written permission. 1511960Sgabeblack@google.com * 1611960Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1711960Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1811960Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1911960Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2011960Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2111960Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2211960Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2311960Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2411960Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2511960Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2611960Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2711960Sgabeblack@google.com * 2811960Sgabeblack@google.com * Authors: Stephen Hines 2911960Sgabeblack@google.com */ 3011960Sgabeblack@google.com 3111960Sgabeblack@google.com#include "arch/arm/isa_traits.hh" 3211960Sgabeblack@google.com#include "arch/arm/process.hh" 3311960Sgabeblack@google.com#include "arch/arm/types.hh" 3411960Sgabeblack@google.com#include "base/loader/elf_object.hh" 3511960Sgabeblack@google.com#include "base/loader/object_file.hh" 3611960Sgabeblack@google.com#include "base/misc.hh" 3711960Sgabeblack@google.com#include "cpu/thread_context.hh" 3811960Sgabeblack@google.com#include "mem/page_table.hh" 3911960Sgabeblack@google.com#include "mem/translating_port.hh" 4011960Sgabeblack@google.com#include "sim/process_impl.hh" 4111960Sgabeblack@google.com#include "sim/system.hh" 4211960Sgabeblack@google.com 4311960Sgabeblack@google.comusing namespace std; 4411960Sgabeblack@google.comusing namespace ArmISA; 4511960Sgabeblack@google.com 4611960Sgabeblack@google.comArmLiveProcess::ArmLiveProcess(LiveProcessParams * params, 4711960Sgabeblack@google.com ObjectFile *objFile) 4811960Sgabeblack@google.com : LiveProcess(params, objFile) 4911960Sgabeblack@google.com{ 5011960Sgabeblack@google.com stack_base = 0xc0000000L; 5111960Sgabeblack@google.com 5211960Sgabeblack@google.com // Set pointer for next thread stack. Reserve 8M for main stack. 5311960Sgabeblack@google.com next_thread_stack_base = stack_base - (8 * 1024 * 1024); 5411960Sgabeblack@google.com 5511960Sgabeblack@google.com // Set up break point (Top of Heap) 5611960Sgabeblack@google.com brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize(); 5711960Sgabeblack@google.com brk_point = roundUp(brk_point, VMPageSize); 5811960Sgabeblack@google.com 5911960Sgabeblack@google.com // Set up region for mmaps. For now, start at bottom of kuseg space. 6011960Sgabeblack@google.com mmap_start = mmap_end = 0x70000000L; 6111960Sgabeblack@google.com} 6211960Sgabeblack@google.com 6311960Sgabeblack@google.comvoid 6411960Sgabeblack@google.comArmLiveProcess::startup() 6511960Sgabeblack@google.com{ 6611960Sgabeblack@google.com argsInit(MachineBytes, VMPageSize); 6711960Sgabeblack@google.com} 6811960Sgabeblack@google.com 6911960Sgabeblack@google.comvoid 7011960Sgabeblack@google.comArmLiveProcess::copyStringArray32(std::vector<std::string> &strings, 7111960Sgabeblack@google.com Addr array_ptr, Addr data_ptr, 7211960Sgabeblack@google.com TranslatingPort* memPort) 7311960Sgabeblack@google.com{ 7411960Sgabeblack@google.com Addr data_ptr_swap; 7511960Sgabeblack@google.com for (int i = 0; i < strings.size(); ++i) { 7611960Sgabeblack@google.com data_ptr_swap = htog(data_ptr); 7711960Sgabeblack@google.com memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr_swap, 7811960Sgabeblack@google.com sizeof(uint32_t)); 7911960Sgabeblack@google.com memPort->writeString(data_ptr, strings[i].c_str()); 8011960Sgabeblack@google.com array_ptr += sizeof(uint32_t); 8111960Sgabeblack@google.com data_ptr += strings[i].size() + 1; 8211960Sgabeblack@google.com } 8311960Sgabeblack@google.com // add NULL terminator 8411960Sgabeblack@google.com data_ptr = 0; 8511960Sgabeblack@google.com 8611960Sgabeblack@google.com memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr, sizeof(uint32_t)); 8711960Sgabeblack@google.com} 8811960Sgabeblack@google.com 8911960Sgabeblack@google.comvoid 9011960Sgabeblack@google.comArmLiveProcess::argsInit(int intSize, int pageSize) 9111960Sgabeblack@google.com{ 9211960Sgabeblack@google.com // Overloaded argsInit so that we can fine-tune for ARM architecture 9311960Sgabeblack@google.com Process::startup(); 9411960Sgabeblack@google.com 9511960Sgabeblack@google.com // load object file into target memory 9611960Sgabeblack@google.com objFile->loadSections(initVirtMem); 9711960Sgabeblack@google.com 9811960Sgabeblack@google.com // Calculate how much space we need for arg & env arrays. 9911960Sgabeblack@google.com int argv_array_size = intSize * (argv.size() + 1); 10011960Sgabeblack@google.com int envp_array_size = intSize * (envp.size() + 1); 10111960Sgabeblack@google.com int arg_data_size = 0; 10211960Sgabeblack@google.com for (int i = 0; i < argv.size(); ++i) { 10311960Sgabeblack@google.com arg_data_size += argv[i].size() + 1; 10411960Sgabeblack@google.com } 10511960Sgabeblack@google.com int env_data_size = 0; 10611960Sgabeblack@google.com for (int i = 0; i < envp.size(); ++i) { 10711960Sgabeblack@google.com env_data_size += envp[i].size() + 1; 10811960Sgabeblack@google.com } 10911960Sgabeblack@google.com 11011960Sgabeblack@google.com int space_needed = 11111960Sgabeblack@google.com argv_array_size + envp_array_size + arg_data_size + env_data_size; 11211960Sgabeblack@google.com if (space_needed < 16*1024) 11311960Sgabeblack@google.com space_needed = 16*1024; 11411960Sgabeblack@google.com 11511960Sgabeblack@google.com // set bottom of stack 11611960Sgabeblack@google.com stack_min = stack_base - space_needed; 11711960Sgabeblack@google.com // align it 11811960Sgabeblack@google.com stack_min = roundDown(stack_min, pageSize); 11911960Sgabeblack@google.com stack_size = stack_base - stack_min; 12011960Sgabeblack@google.com // map memory 12111960Sgabeblack@google.com pTable->allocate(stack_min, roundUp(stack_size, pageSize)); 12211960Sgabeblack@google.com 12311960Sgabeblack@google.com // map out initial stack contents 12411960Sgabeblack@google.com Addr argv_array_base = stack_min + intSize; // room for argc 12511960Sgabeblack@google.com Addr envp_array_base = argv_array_base + argv_array_size; 12611960Sgabeblack@google.com Addr arg_data_base = envp_array_base + envp_array_size; 12711960Sgabeblack@google.com Addr env_data_base = arg_data_base + arg_data_size; 12811960Sgabeblack@google.com 12911960Sgabeblack@google.com // write contents to stack 13011960Sgabeblack@google.com uint64_t argc = argv.size(); 13111960Sgabeblack@google.com if (intSize == 8) 13211960Sgabeblack@google.com argc = htog((uint64_t)argc); 13311960Sgabeblack@google.com else if (intSize == 4) 13411960Sgabeblack@google.com argc = htog((uint32_t)argc); 13511960Sgabeblack@google.com else 13611960Sgabeblack@google.com panic("Unknown int size"); 13711960Sgabeblack@google.com 13811960Sgabeblack@google.com initVirtMem->writeBlob(stack_min, (uint8_t*)&argc, intSize); 13911960Sgabeblack@google.com 14011960Sgabeblack@google.com copyStringArray32(argv, argv_array_base, arg_data_base, initVirtMem); 14111960Sgabeblack@google.com copyStringArray32(envp, envp_array_base, env_data_base, initVirtMem); 14211960Sgabeblack@google.com 14311960Sgabeblack@google.com /* 14411960Sgabeblack@google.com //uint8_t insns[] = {0xe5, 0x9f, 0x00, 0x08, 0xe1, 0xa0, 0xf0, 0x0e}; 14511960Sgabeblack@google.com uint8_t insns[] = {0x08, 0x00, 0x9f, 0xe5, 0x0e, 0xf0, 0xa0, 0xe1}; 14611960Sgabeblack@google.com 14711960Sgabeblack@google.com initVirtMem->writeBlob(0xffff0fe0, insns, 8); 14811960Sgabeblack@google.com */ 14911960Sgabeblack@google.com 15011960Sgabeblack@google.com threadContexts[0]->setIntReg(ArgumentReg1, argc); 15111960Sgabeblack@google.com threadContexts[0]->setIntReg(ArgumentReg2, argv_array_base); 15211960Sgabeblack@google.com threadContexts[0]->setIntReg(StackPointerReg, stack_min); 15311960Sgabeblack@google.com 15411960Sgabeblack@google.com Addr prog_entry = objFile->entryPoint(); 15511960Sgabeblack@google.com threadContexts[0]->setPC(prog_entry); 15611960Sgabeblack@google.com threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst)); 15711960Sgabeblack@google.com} 15811960Sgabeblack@google.com 15911960Sgabeblack@google.com