process.cc revision 8232:b28d06a175be
12315SN/A/* 212107SRekai.GonzalezAlberquilla@arm.com * Copyright (c) 2010 ARM Limited 39913Ssteve.reinhardt@amd.com * All rights reserved 48733Sgeoffrey.blake@arm.com * 58733Sgeoffrey.blake@arm.com * The license below extends only to copyright in the software and shall 68733Sgeoffrey.blake@arm.com * not be construed as granting a license to any other intellectual 78733Sgeoffrey.blake@arm.com * property including but not limited to intellectual property relating 88733Sgeoffrey.blake@arm.com * to a hardware implementation of the functionality of the software 98733Sgeoffrey.blake@arm.com * licensed hereunder. You may use the software subject to the license 108733Sgeoffrey.blake@arm.com * terms below provided that you ensure that this notice is replicated 118733Sgeoffrey.blake@arm.com * unmodified and in its entirety in all distributions of the software, 128733Sgeoffrey.blake@arm.com * modified or unmodified, in source code or in binary form. 138733Sgeoffrey.blake@arm.com * 148733Sgeoffrey.blake@arm.com * Copyright (c) 2007-2008 The Florida State University 152332SN/A * All rights reserved. 162315SN/A * 172315SN/A * Redistribution and use in source and binary forms, with or without 182315SN/A * modification, are permitted provided that the following conditions are 192315SN/A * met: redistributions of source code must retain the above copyright 202315SN/A * notice, this list of conditions and the following disclaimer; 212315SN/A * redistributions in binary form must reproduce the above copyright 222315SN/A * notice, this list of conditions and the following disclaimer in the 232315SN/A * documentation and/or other materials provided with the distribution; 242315SN/A * neither the name of the copyright holders nor the names of its 252315SN/A * contributors may be used to endorse or promote products derived from 262315SN/A * this software without specific prior written permission. 272315SN/A * 282315SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 292315SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 302315SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 312315SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 322315SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 332315SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 342315SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 352315SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 362315SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 372315SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 382315SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 392315SN/A * 402689SN/A * Authors: Stephen Hines 412689SN/A * Ali Saidi 428733Sgeoffrey.blake@arm.com */ 432315SN/A 442315SN/A#include "arch/arm/isa_traits.hh" 459944Smatt.horsnell@ARM.com#include "arch/arm/process.hh" 469944Smatt.horsnell@ARM.com#include "arch/arm/types.hh" 479944Smatt.horsnell@ARM.com#include "base/loader/elf_object.hh" 482315SN/A#include "base/loader/object_file.hh" 492315SN/A#include "base/misc.hh" 502315SN/A#include "cpu/thread_context.hh" 518888Sgeoffrey.blake@arm.com#include "debug/Stack.hh" 528793Sgblack@eecs.umich.edu#include "mem/page_table.hh" 532315SN/A#include "mem/translating_port.hh" 546658Snate@binkert.org#include "sim/byteswap.hh" 552315SN/A#include "sim/process_impl.hh" 568733Sgeoffrey.blake@arm.com#include "sim/system.hh" 579913Ssteve.reinhardt@amd.com 582683SN/Ausing namespace std; 598229Snate@binkert.orgusing namespace ArmISA; 602680SN/A 618733Sgeoffrey.blake@arm.comArmLiveProcess::ArmLiveProcess(LiveProcessParams *params, ObjectFile *objFile, 628733Sgeoffrey.blake@arm.com ObjectFile::Arch _arch) 638793Sgblack@eecs.umich.edu : LiveProcess(params, objFile), arch(_arch) 642315SN/A{ 652315SN/A stack_base = 0xbf000000L; 662315SN/A 672315SN/A // Set pointer for next thread stack. Reserve 8M for main stack. 688733Sgeoffrey.blake@arm.com next_thread_stack_base = stack_base - (8 * 1024 * 1024); 692315SN/A 708733Sgeoffrey.blake@arm.com // Set up break point (Top of Heap) 712315SN/A brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize(); 7210379Sandreas.hansson@arm.com brk_point = roundUp(brk_point, VMPageSize); 738733Sgeoffrey.blake@arm.com 748733Sgeoffrey.blake@arm.com // Set up region for mmaps. For now, start at bottom of kuseg space. 758733Sgeoffrey.blake@arm.com mmap_start = mmap_end = 0x40000000L; 768733Sgeoffrey.blake@arm.com} 779023Sgblack@eecs.umich.edu 788733Sgeoffrey.blake@arm.comvoid 798733Sgeoffrey.blake@arm.comArmLiveProcess::initState() 808733Sgeoffrey.blake@arm.com{ 818733Sgeoffrey.blake@arm.com LiveProcess::initState(); 828733Sgeoffrey.blake@arm.com argsInit(MachineBytes, VMPageSize); 838733Sgeoffrey.blake@arm.com for (int i = 0; i < contextIds.size(); i++) { 848733Sgeoffrey.blake@arm.com ThreadContext * tc = system->getThreadContext(contextIds[i]); 858733Sgeoffrey.blake@arm.com CPACR cpacr = tc->readMiscReg(MISCREG_CPACR); 868733Sgeoffrey.blake@arm.com // Enable the floating point coprocessors. 878733Sgeoffrey.blake@arm.com cpacr.cp10 = 0x3; 888733Sgeoffrey.blake@arm.com cpacr.cp11 = 0x3; 898733Sgeoffrey.blake@arm.com tc->setMiscReg(MISCREG_CPACR, cpacr); 908733Sgeoffrey.blake@arm.com // Generically enable floating point support. 918733Sgeoffrey.blake@arm.com FPEXC fpexc = tc->readMiscReg(MISCREG_FPEXC); 928733Sgeoffrey.blake@arm.com fpexc.en = 1; 938733Sgeoffrey.blake@arm.com tc->setMiscReg(MISCREG_FPEXC, fpexc); 948733Sgeoffrey.blake@arm.com } 958733Sgeoffrey.blake@arm.com} 968733Sgeoffrey.blake@arm.com 978733Sgeoffrey.blake@arm.comvoid 988733Sgeoffrey.blake@arm.comArmLiveProcess::argsInit(int intSize, int pageSize) 998733Sgeoffrey.blake@arm.com{ 1008733Sgeoffrey.blake@arm.com typedef AuxVector<uint32_t> auxv_t; 1018733Sgeoffrey.blake@arm.com std::vector<auxv_t> auxv; 1028733Sgeoffrey.blake@arm.com 1038733Sgeoffrey.blake@arm.com string filename; 1048733Sgeoffrey.blake@arm.com if (argv.size() < 1) 1058733Sgeoffrey.blake@arm.com filename = ""; 1068733Sgeoffrey.blake@arm.com else 1078733Sgeoffrey.blake@arm.com filename = argv[0]; 1088733Sgeoffrey.blake@arm.com 1098733Sgeoffrey.blake@arm.com //We want 16 byte alignment 1108733Sgeoffrey.blake@arm.com uint64_t align = 16; 1118733Sgeoffrey.blake@arm.com 1128733Sgeoffrey.blake@arm.com // load object file into target memory 1138733Sgeoffrey.blake@arm.com objFile->loadSections(initVirtMem); 1148733Sgeoffrey.blake@arm.com 1158733Sgeoffrey.blake@arm.com enum ArmCpuFeature { 1168733Sgeoffrey.blake@arm.com Arm_Swp = 1 << 0, 1178733Sgeoffrey.blake@arm.com Arm_Half = 1 << 1, 1188733Sgeoffrey.blake@arm.com Arm_Thumb = 1 << 2, 1198733Sgeoffrey.blake@arm.com Arm_26Bit = 1 << 3, 1208733Sgeoffrey.blake@arm.com Arm_FastMult = 1 << 4, 1219023Sgblack@eecs.umich.edu Arm_Fpa = 1 << 5, 1228733Sgeoffrey.blake@arm.com Arm_Vfp = 1 << 6, 1238733Sgeoffrey.blake@arm.com Arm_Edsp = 1 << 7, 1248733Sgeoffrey.blake@arm.com Arm_Java = 1 << 8, 1258733Sgeoffrey.blake@arm.com Arm_Iwmmxt = 1 << 9, 1268733Sgeoffrey.blake@arm.com Arm_Crunch = 1 << 10, 12713429Srekai.gonzalezalberquilla@arm.com Arm_ThumbEE = 1 << 11, 1282315SN/A Arm_Neon = 1 << 12, 1292315SN/A Arm_Vfpv3 = 1 << 13, 1302315SN/A Arm_Vfpv3d16 = 1 << 14 1318733Sgeoffrey.blake@arm.com }; 1328733Sgeoffrey.blake@arm.com 1338733Sgeoffrey.blake@arm.com //Setup the auxilliary vectors. These will already have endian conversion. 1348733Sgeoffrey.blake@arm.com //Auxilliary vectors are loaded only for elf formatted executables. 1358733Sgeoffrey.blake@arm.com ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile); 1368733Sgeoffrey.blake@arm.com if (elfObject) { 1378733Sgeoffrey.blake@arm.com uint32_t features = 1388733Sgeoffrey.blake@arm.com Arm_Swp | 1398733Sgeoffrey.blake@arm.com Arm_Half | 1408733Sgeoffrey.blake@arm.com Arm_Thumb | 1418733Sgeoffrey.blake@arm.com// Arm_26Bit | 1428733Sgeoffrey.blake@arm.com Arm_FastMult | 1432332SN/A// Arm_Fpa | 1442332SN/A Arm_Vfp | 1452332SN/A Arm_Edsp | 1462332SN/A// Arm_Java | 1472332SN/A// Arm_Iwmmxt | 1482315SN/A// Arm_Crunch | 1492315SN/A Arm_ThumbEE | 1508733Sgeoffrey.blake@arm.com Arm_Neon | 1518733Sgeoffrey.blake@arm.com Arm_Vfpv3 | 1522315SN/A Arm_Vfpv3d16 | 1532315SN/A 0; 1542315SN/A 1552315SN/A //Bits which describe the system hardware capabilities 1562315SN/A //XXX Figure out what these should be 1572315SN/A auxv.push_back(auxv_t(M5_AT_HWCAP, features)); 1582315SN/A //The system page size 1592315SN/A auxv.push_back(auxv_t(M5_AT_PAGESZ, ArmISA::VMPageSize)); 1602315SN/A //Frequency at which times() increments 1612315SN/A auxv.push_back(auxv_t(M5_AT_CLKTCK, 0x64)); 1622315SN/A // For statically linked executables, this is the virtual address of the 1632315SN/A // program header tables if they appear in the executable image 1642315SN/A auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable())); 1658733Sgeoffrey.blake@arm.com // This is the size of a program header entry from the elf file. 1668733Sgeoffrey.blake@arm.com auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize())); 1672315SN/A // This is the number of program headers from the original elf file. 1682315SN/A auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount())); 1692315SN/A //This is the address of the elf "interpreter", It should be set 1702315SN/A //to 0 for regular executables. It should be something else 1712315SN/A //(not sure what) for dynamic libraries. 1722315SN/A auxv.push_back(auxv_t(M5_AT_BASE, 0)); 1732315SN/A 1742315SN/A //XXX Figure out what this should be. 1752315SN/A auxv.push_back(auxv_t(M5_AT_FLAGS, 0)); 1762315SN/A //The entry point to the program 1772315SN/A auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint())); 1782315SN/A //Different user and group IDs 1792315SN/A auxv.push_back(auxv_t(M5_AT_UID, uid())); 1802315SN/A auxv.push_back(auxv_t(M5_AT_EUID, euid())); 1818733Sgeoffrey.blake@arm.com auxv.push_back(auxv_t(M5_AT_GID, gid())); 1828733Sgeoffrey.blake@arm.com auxv.push_back(auxv_t(M5_AT_EGID, egid())); 1838733Sgeoffrey.blake@arm.com //Whether to enable "secure mode" in the executable 1848733Sgeoffrey.blake@arm.com auxv.push_back(auxv_t(M5_AT_SECURE, 0)); 1858733Sgeoffrey.blake@arm.com 1868733Sgeoffrey.blake@arm.com // Pointer to 16 bytes of random data 1878733Sgeoffrey.blake@arm.com auxv.push_back(auxv_t(M5_AT_RANDOM, 0)); 1882354SN/A 1898733Sgeoffrey.blake@arm.com //The filename of the program 1902354SN/A auxv.push_back(auxv_t(M5_AT_EXECFN, 0)); 1912332SN/A //The string "v71" -- ARM v7 architecture 1922332SN/A auxv.push_back(auxv_t(M5_AT_PLATFORM, 0)); 1932332SN/A } 1942315SN/A 1958733Sgeoffrey.blake@arm.com //Figure out how big the initial stack nedes to be 1968733Sgeoffrey.blake@arm.com 1978733Sgeoffrey.blake@arm.com // A sentry NULL void pointer at the top of the stack. 1988733Sgeoffrey.blake@arm.com int sentry_size = intSize; 1998733Sgeoffrey.blake@arm.com 2008733Sgeoffrey.blake@arm.com string platform = "v71"; 2018733Sgeoffrey.blake@arm.com int platform_size = platform.size() + 1; 2028733Sgeoffrey.blake@arm.com 2038733Sgeoffrey.blake@arm.com // Bytes for AT_RANDOM above, we'll just keep them 0 2042315SN/A int aux_random_size = 16; // as per the specification 2052315SN/A 2062315SN/A // The aux vectors are put on the stack in two groups. The first group are 2072315SN/A // the vectors that are generated as the elf is loaded. The second group 2082315SN/A // are the ones that were computed ahead of time and include the platform 2092683SN/A // string. 2108888Sgeoffrey.blake@arm.com int aux_data_size = filename.size() + 1; 21113611Sgabeblack@google.com 2128888Sgeoffrey.blake@arm.com int env_data_size = 0; 2132315SN/A for (int i = 0; i < envp.size(); ++i) { 2142332SN/A env_data_size += envp[i].size() + 1; 2152332SN/A } 2162332SN/A int arg_data_size = 0; 2172315SN/A for (int i = 0; i < argv.size(); ++i) { 2188733Sgeoffrey.blake@arm.com arg_data_size += argv[i].size() + 1; 2198733Sgeoffrey.blake@arm.com } 2202315SN/A 2218733Sgeoffrey.blake@arm.com int info_block_size = 2222315SN/A sentry_size + env_data_size + arg_data_size + 2232315SN/A aux_data_size + platform_size + aux_random_size; 2242332SN/A 2258733Sgeoffrey.blake@arm.com //Each auxilliary vector is two 4 byte words 2268733Sgeoffrey.blake@arm.com int aux_array_size = intSize * 2 * (auxv.size() + 1); 2272732SN/A 2282315SN/A int envp_array_size = intSize * (envp.size() + 1); 2292315SN/A int argv_array_size = intSize * (argv.size() + 1); 2302315SN/A 2312315SN/A int argc_size = intSize; 2322315SN/A 2332315SN/A //Figure out the size of the contents of the actual initial frame 2342332SN/A int frame_size = 2358733Sgeoffrey.blake@arm.com info_block_size + 2368733Sgeoffrey.blake@arm.com aux_array_size + 2372332SN/A envp_array_size + 2388733Sgeoffrey.blake@arm.com argv_array_size + 2398733Sgeoffrey.blake@arm.com argc_size; 2408733Sgeoffrey.blake@arm.com 2412332SN/A //There needs to be padding after the auxiliary vector data so that the 2429023Sgblack@eecs.umich.edu //very bottom of the stack is aligned properly. 2439023Sgblack@eecs.umich.edu int partial_size = frame_size; 2448733Sgeoffrey.blake@arm.com int aligned_partial_size = roundUp(partial_size, align); 2458733Sgeoffrey.blake@arm.com int aux_padding = aligned_partial_size - partial_size; 2468733Sgeoffrey.blake@arm.com 24712749Sgiacomo.travaglini@arm.com int space_needed = frame_size + aux_padding; 24812749Sgiacomo.travaglini@arm.com 24912749Sgiacomo.travaglini@arm.com stack_min = stack_base - space_needed; 25012749Sgiacomo.travaglini@arm.com stack_min = roundDown(stack_min, align); 2512679SN/A stack_size = stack_base - stack_min; 25212749Sgiacomo.travaglini@arm.com 25312749Sgiacomo.travaglini@arm.com // map memory 25412749Sgiacomo.travaglini@arm.com pTable->allocate(roundDown(stack_min, pageSize), 2552315SN/A roundUp(stack_size, pageSize)); 25612749Sgiacomo.travaglini@arm.com 25712749Sgiacomo.travaglini@arm.com // map out initial stack contents 2582315SN/A uint32_t sentry_base = stack_base - sentry_size; 2598733Sgeoffrey.blake@arm.com uint32_t aux_data_base = sentry_base - aux_data_size; 2608733Sgeoffrey.blake@arm.com uint32_t env_data_base = aux_data_base - env_data_size; 2618733Sgeoffrey.blake@arm.com uint32_t arg_data_base = env_data_base - arg_data_size; 2628733Sgeoffrey.blake@arm.com uint32_t platform_base = arg_data_base - platform_size; 2638733Sgeoffrey.blake@arm.com uint32_t aux_random_base = platform_base - aux_random_size; 2648733Sgeoffrey.blake@arm.com uint32_t auxv_array_base = aux_random_base - aux_array_size - aux_padding; 2658733Sgeoffrey.blake@arm.com uint32_t envp_array_base = auxv_array_base - envp_array_size; 2668733Sgeoffrey.blake@arm.com uint32_t argv_array_base = envp_array_base - argv_array_size; 2678733Sgeoffrey.blake@arm.com uint32_t argc_base = argv_array_base - argc_size; 2688733Sgeoffrey.blake@arm.com 2692315SN/A DPRINTF(Stack, "The addresses of items on the initial stack:\n"); 2708733Sgeoffrey.blake@arm.com DPRINTF(Stack, "0x%x - aux data\n", aux_data_base); 2718733Sgeoffrey.blake@arm.com DPRINTF(Stack, "0x%x - env data\n", env_data_base); 2722315SN/A DPRINTF(Stack, "0x%x - arg data\n", arg_data_base); 2738733Sgeoffrey.blake@arm.com DPRINTF(Stack, "0x%x - random data\n", aux_random_base); 2748733Sgeoffrey.blake@arm.com DPRINTF(Stack, "0x%x - platform base\n", platform_base); 2758733Sgeoffrey.blake@arm.com DPRINTF(Stack, "0x%x - auxv array\n", auxv_array_base); 2768733Sgeoffrey.blake@arm.com DPRINTF(Stack, "0x%x - envp array\n", envp_array_base); 2778733Sgeoffrey.blake@arm.com DPRINTF(Stack, "0x%x - argv array\n", argv_array_base); 2788733Sgeoffrey.blake@arm.com DPRINTF(Stack, "0x%x - argc \n", argc_base); 2798733Sgeoffrey.blake@arm.com DPRINTF(Stack, "0x%x - stack min\n", stack_min); 2808733Sgeoffrey.blake@arm.com 2818733Sgeoffrey.blake@arm.com // write contents to stack 2828733Sgeoffrey.blake@arm.com 2838733Sgeoffrey.blake@arm.com // figure out argc 28412749Sgiacomo.travaglini@arm.com uint32_t argc = argv.size(); 2858733Sgeoffrey.blake@arm.com uint32_t guestArgc = ArmISA::htog(argc); 2868733Sgeoffrey.blake@arm.com 2878733Sgeoffrey.blake@arm.com //Write out the sentry void * 2888733Sgeoffrey.blake@arm.com uint32_t sentry_NULL = 0; 2898733Sgeoffrey.blake@arm.com initVirtMem->writeBlob(sentry_base, 2908733Sgeoffrey.blake@arm.com (uint8_t*)&sentry_NULL, sentry_size); 2918733Sgeoffrey.blake@arm.com 2928733Sgeoffrey.blake@arm.com //Fix up the aux vectors which point to other data 2938733Sgeoffrey.blake@arm.com for (int i = auxv.size() - 1; i >= 0; i--) { 2948733Sgeoffrey.blake@arm.com if (auxv[i].a_type == M5_AT_PLATFORM) { 2958733Sgeoffrey.blake@arm.com auxv[i].a_val = platform_base; 2968733Sgeoffrey.blake@arm.com initVirtMem->writeString(platform_base, platform.c_str()); 2978733Sgeoffrey.blake@arm.com } else if (auxv[i].a_type == M5_AT_EXECFN) { 2988733Sgeoffrey.blake@arm.com auxv[i].a_val = aux_data_base; 2998733Sgeoffrey.blake@arm.com initVirtMem->writeString(aux_data_base, filename.c_str()); 3008733Sgeoffrey.blake@arm.com } else if (auxv[i].a_type == M5_AT_RANDOM) { 3018733Sgeoffrey.blake@arm.com auxv[i].a_val = aux_random_base; 3028733Sgeoffrey.blake@arm.com // Just leave the value 0, we don't want randomness 30310417Sandreas.hansson@arm.com } 3048733Sgeoffrey.blake@arm.com } 3058733Sgeoffrey.blake@arm.com 3068733Sgeoffrey.blake@arm.com //Copy the aux stuff 3078733Sgeoffrey.blake@arm.com for(int x = 0; x < auxv.size(); x++) 3089023Sgblack@eecs.umich.edu { 3098733Sgeoffrey.blake@arm.com initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize, 3108733Sgeoffrey.blake@arm.com (uint8_t*)&(auxv[x].a_type), intSize); 3118733Sgeoffrey.blake@arm.com initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize, 3128733Sgeoffrey.blake@arm.com (uint8_t*)&(auxv[x].a_val), intSize); 3139023Sgblack@eecs.umich.edu } 3148733Sgeoffrey.blake@arm.com //Write out the terminating zeroed auxilliary vector 3159023Sgblack@eecs.umich.edu const uint64_t zero = 0; 3168733Sgeoffrey.blake@arm.com initVirtMem->writeBlob(auxv_array_base + 2 * intSize * auxv.size(), 3178733Sgeoffrey.blake@arm.com (uint8_t*)&zero, 2 * intSize); 3188733Sgeoffrey.blake@arm.com 3198733Sgeoffrey.blake@arm.com copyStringArray(envp, envp_array_base, env_data_base, initVirtMem); 3208733Sgeoffrey.blake@arm.com copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem); 3218733Sgeoffrey.blake@arm.com 3228733Sgeoffrey.blake@arm.com initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize); 3238733Sgeoffrey.blake@arm.com 3248733Sgeoffrey.blake@arm.com ThreadContext *tc = system->getThreadContext(contextIds[0]); 3258733Sgeoffrey.blake@arm.com //Set the stack pointer register 3268733Sgeoffrey.blake@arm.com tc->setIntReg(StackPointerReg, stack_min); 3278733Sgeoffrey.blake@arm.com //A pointer to a function to run when the program exits. We'll set this 3288733Sgeoffrey.blake@arm.com //to zero explicitly to make sure this isn't used. 3298733Sgeoffrey.blake@arm.com tc->setIntReg(ArgumentReg0, 0); 3308733Sgeoffrey.blake@arm.com //Set argument regs 1 and 2 to argv[0] and envp[0] respectively 3318733Sgeoffrey.blake@arm.com if (argv.size() > 0) { 3328733Sgeoffrey.blake@arm.com tc->setIntReg(ArgumentReg1, arg_data_base + arg_data_size - 3338733Sgeoffrey.blake@arm.com argv[argv.size() - 1].size() - 1); 3348733Sgeoffrey.blake@arm.com } else { 3358733Sgeoffrey.blake@arm.com tc->setIntReg(ArgumentReg1, 0); 3368733Sgeoffrey.blake@arm.com } 3372323SN/A if (envp.size() > 0) { 3382315SN/A tc->setIntReg(ArgumentReg2, env_data_base + env_data_size - 3399023Sgblack@eecs.umich.edu envp[envp.size() - 1].size() - 1); 3409023Sgblack@eecs.umich.edu } else { 3412315SN/A tc->setIntReg(ArgumentReg2, 0); 3428733Sgeoffrey.blake@arm.com } 3438733Sgeoffrey.blake@arm.com 3448733Sgeoffrey.blake@arm.com PCState pc; 3452323SN/A pc.thumb(arch == ObjectFile::Thumb); 3468733Sgeoffrey.blake@arm.com pc.nextThumb(pc.thumb()); 3472679SN/A pc.set(objFile->entryPoint() & ~mask(1)); 3482323SN/A tc->pcState(pc); 3492323SN/A 3508733Sgeoffrey.blake@arm.com //Align the "stack_min" to a page boundary. 3512323SN/A stack_min = roundDown(stack_min, pageSize); 3522315SN/A} 3538733Sgeoffrey.blake@arm.com 3548733Sgeoffrey.blake@arm.comArmISA::IntReg 3558733Sgeoffrey.blake@arm.comArmLiveProcess::getSyscallArg(ThreadContext *tc, int &i) 3562679SN/A{ 3572315SN/A assert(i < 6); 3582315SN/A return tc->readIntReg(ArgumentReg0 + i++); 3592315SN/A} 3602315SN/A 3618733Sgeoffrey.blake@arm.comuint64_t 3628733Sgeoffrey.blake@arm.comArmLiveProcess::getSyscallArg(ThreadContext *tc, int &i, int width) 3638733Sgeoffrey.blake@arm.com{ 3648733Sgeoffrey.blake@arm.com assert(width == 32 || width == 64); 3658733Sgeoffrey.blake@arm.com if (width == 32) 3668733Sgeoffrey.blake@arm.com return getSyscallArg(tc, i); 3678733Sgeoffrey.blake@arm.com 3688733Sgeoffrey.blake@arm.com // 64 bit arguments are passed starting in an even register 3698733Sgeoffrey.blake@arm.com if (i % 2 != 0) 3708733Sgeoffrey.blake@arm.com i++; 3718733Sgeoffrey.blake@arm.com 3728733Sgeoffrey.blake@arm.com // Registers r0-r6 can be used 3738733Sgeoffrey.blake@arm.com assert(i < 5); 3742315SN/A uint64_t val; 3758733Sgeoffrey.blake@arm.com val = tc->readIntReg(ArgumentReg0 + i++); 3768733Sgeoffrey.blake@arm.com val |= ((uint64_t)tc->readIntReg(ArgumentReg0 + i++) << 32); 3778733Sgeoffrey.blake@arm.com return val; 3788733Sgeoffrey.blake@arm.com} 3792315SN/A 3808733Sgeoffrey.blake@arm.com 3818733Sgeoffrey.blake@arm.comvoid 3828733Sgeoffrey.blake@arm.comArmLiveProcess::setSyscallArg(ThreadContext *tc, 3838733Sgeoffrey.blake@arm.com int i, ArmISA::IntReg val) 3848733Sgeoffrey.blake@arm.com{ 3858733Sgeoffrey.blake@arm.com assert(i < 4); 3868733Sgeoffrey.blake@arm.com tc->setIntReg(ArgumentReg0 + i, val); 3878733Sgeoffrey.blake@arm.com} 3888733Sgeoffrey.blake@arm.com 3898733Sgeoffrey.blake@arm.comvoid 3908733Sgeoffrey.blake@arm.comArmLiveProcess::setSyscallReturn(ThreadContext *tc, 3912315SN/A SyscallReturn return_value) 3922315SN/A{ 3932315SN/A tc->setIntReg(ReturnValueReg, return_value.value()); 3948733Sgeoffrey.blake@arm.com} 3952315SN/A