📄 solo_main.c
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees * of Leland Stanford Junior University. * * This file is part of the SimOS distribution. * See LICENSE file for terms of the license. * *//***************************************************************** * solo_main.c * *****************************************************************/#include <filehdr.h>#include <aouthdr.h>#include <elf.h>#include <setjmp.h>#include <sys/types.h>#include <unistd.h>#include <fcntl.h>#include <stdio.h>#include "eventcallback.h"#include "annotations.h"#undef SHARED#include <sys/mman.h>#include "mipsy.h"#include "solo.h"#include "solo_interface.h"#include "solo_extras.h"#include "solo_page.h"#include "solo_anl.h"#include <stdlib.h>#include <filehdr.h>#include <aouthdr.h>#include <elf.h>#include <sys/param.h> /* For btoc/ctob */#include <sys/sysmacros.h> /* For btoc/ctob */extern int __elfmap(char *, int, int); /* internal LIBC routines */extern VA SetupStack(int , char **, int, char **, void *);extern char **_environ;extern void HWEventsLateInit(void);extern void SymLoad(char *, char *);char *AppBrk; /* The brk point of the application */char *progName;extern int SimErrorKeepLogs;int soloActiveProcs = 1;VA soloHighStack; VA soloLowStack;int soloCPUNum;int restoringCpt = 0;#ifdef T5_MODELvoid *entryPC;#endifCommArea *comm;voidDumpMipsyConfig(void){ CPUPrint("Options from Mipsy build:\n--> "); CPUPrint(" SOLO");#ifdef T5_MODEL CPUPrint(" T5_MODEL\n");#endif SIM_DEBUG(('o', " ANL_DEBUG DEBUG_SYSCALL")); CPUPrint("\nDebug options from Mipsy build:\n--> ");#ifdef DEBUG_DATA CPUPrint(" DEBUG_DATA");#endif#ifdef DEBUG_DATA_VERBOSE CPUPrint(" DEBUG_DATA_VERBOSE");#endif CPUPrint("\n\n");}extern void TCLInit(char *initFile);/***************************************************************** * SoloTCLInit *****************************************************************/void SoloTclInit(Tcl_Interp *interp){ Tcl_SetVar(interp, "simosPath", ". /morse/m3/hive/simulation/apps/tcl", TCL_GLOBAL_ONLY); SymLoad(progName, "soloApp");}static voidUsage(void){ fprintf(stderr, "\nusage: solo [-d <debug flags>] application_and_args\n");}char *progName = NULL;/***************************************************************** * Entrance to solo mipsy. This main routine will load the application * into memory and start its execution. *****************************************************************/intmain(int argc, char **argv){ int i, fd, length, page; char *addr; struct filehdr *fhdr; Elf32_Ehdr *ehdr; Elf32_Phdr *phdr; char *phdrbase; void *entryPC; int elen; VA stackStart; uint curbrk = 0; uint textStart; bool mprotectFailed = FALSE; int c; const uint pagesize = getpagesize(); /* This is a hack to make sure ld keeps syscall.o in the link */ extern int SoloEmulateSyscall(int cpuNum, int syscallNum); void *bar = SoloEmulateSyscall; /* This is a hack to make sure ld keeps solo_stubs.o in the link */ extern void *Simrmt_mmap(void *addr, size_t len, int prot, int flags, char* pathName, off_t off); void *bar2 = Simrmt_mmap; if (argc < 2) { Usage(); exit(1); } SimErrorKeepLogs = 0; SimErrorInit("cpu.log"); /* DebugInit("o"); */ progName = argv[1]; /* Read the application into low memory */ if ((fhdr = (struct filehdr *)__elfmap(progName, 0, 0)) == (struct filehdr *) -1) { printf("Mipsy: mapping of %s failed\n", progName); return -1; } /* Obtain the entrypoint to the program */ ehdr = (Elf32_Ehdr *)fhdr; if (!IS_ELF(*ehdr)) { printf("Can't handle non-ELF object files\n"); abort(); } entryPC = (void *) (ehdr->e_entry); textStart = ((int)entryPC - ((int)entryPC % pagesize)); phdrbase = (char *) ehdr + (ehdr->e_phoff); for (i = 0; i < (int) ehdr->e_phnum; i++) { phdr = (Elf32_Phdr *) (phdrbase + (ehdr->e_phentsize*i)); if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W)) { if (phdr->p_vaddr > curbrk ) { curbrk = phdr->p_vaddr + phdr->p_memsz; } } } /* * I want to be able to use the debugger, and it needs permission * to write "BREAK" to the text segment. */ for (page = 0; mprotectFailed == FALSE; page ++) { if (mprotect((void *)(textStart + (page * pagesize)), pagesize, PROT_WRITE|PROT_READ|PROT_EXEC)) { mprotectFailed = TRUE; } } TCLInit("init.solo"); /***************************************************************** DON'T PRINT ANYTHING BEFORE THIS POINT OR SAVEOLDCPULOGS WON'T WORK ANYMORE *****************************************************************/ AppBrk = (char *) (((curbrk+pagesize-1) / pagesize) * pagesize); /* * Allocate a file to be mapped and used as a shared memory region * for communication between solo mipsy and the application */ fd = open("/dev/zero", O_RDWR); if (fd == -1) { CPUError("/dev/zero open (for comm area mapping) failed"); } length = COMM_LENGTH; addr = (char *) mmap((void *) COMM_START, length, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, 0); if (addr != (char *) COMM_START) { perror("Mapping communication area"); (void) close(fd); } CPUPrint("Mipsy: Mapped comm area from %8.8x to %8.8x\n",COMM_START, COMM_START+length); /* * Fill in the communication area. */ comm = (CommArea *) addr; comm->SetupCommArea = &SoloSetupCommArea; /* * Map a stack in for the application */ fd = open("/dev/zero", O_RDWR); if (fd == -1) { printf("/dev/zero open (for stack mapping) failed"); } addr = (char *) mmap((void *) (SOLO_STACK_TOP - SOLO_STACK_SIZE), SOLO_STACK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, 0); if (addr != (char *) (SOLO_STACK_TOP - SOLO_STACK_SIZE)) { perror("Mapping stack for application"); (void) close(fd); return -1; }#ifdef T5_MODEL CPUPrint("*** Installing T5 model entry point in stack at %8.8x: %8.8x\n", SOLO_STACK_TOP - (SOLO_STACK_SIZE/2), entryPC); * (unsigned long long *)(SOLO_STACK_TOP - (SOLO_STACK_SIZE/2)) = (unsigned long long) entryPC; /* Write the entry vector into the top doubleword of the T5 model stack. */#endif /* * Map an initial heap for the application */ fd = open("/dev/zero", O_RDWR); if (fd == -1) { CPUError("brk emulation: /dev/zero open (for heap mmap) failed"); } addr = (char *) mmap((void *) AppBrk, 0x100000, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, 0); if (addr != (char *) (AppBrk)) { perror("Mapping new heap region for application"); (void) close(fd); return -1; } AppBrk += 0x100000; /* Indicate the real brk value for me */ /* ---- */ for (elen = 0; _environ[elen] != 0; elen++) continue; /* Allow room on the stack for the initial program arguments */ stackStart = (VA)SOLO_STACK_TOP - 0x1000; stackStart = SetupStack(argc-1, argv+1, elen+1, _environ, (void *)stackStart); soloHighStack = stackStart; soloLowStack = stackStart - SOLO_STACK_SIZE; /* Print out the invocation line. */ CPUPrint("Invocation: "); for (i=0; i<argc; i++) { CPUPrint("%s ", argv[i]); } CPUPrint("\n"); CPUPrint("Mipsy: Stack start %#x\n", soloHighStack); CPUPrint("Mipsy: Mapped application stack from %#x to %#x\n", SOLO_STACK_TOP - SOLO_STACK_SIZE, SOLO_STACK_TOP); CPUPrint("COMMSTART= %#x STACK_START= %#x\n", COMM_START, SOLO_STACK_TOP); CPUPrint("Mipsy: Mapped comm area from %#x to %#x\n",COMM_START, COMM_START+length); /* Round to next click (page) */ CPUPrint("Mipsy: Application heap starts at %#x\n", AppBrk); PE = (CPUState *)malloc(TOTAL_CPUS*sizeof(CPUState)); EventCallbackInit(TOTAL_CPUS); SoloInitPageTranslation(); MipsySoloInit(); DumpMipsyConfig(); MipsyStartCPU(0, (VA)entryPC, (VA)0, stackStart); HWEventsLateInit(); CPUPrint("Starting Solo Mipsy CPU 1 at PC 0x%x\n", entryPC); MipsyRun(0); SoloExit(); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -