📄 sesl_tcl.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. * *//* Tcl interface to symbol commands.*/#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <netinet/in.h>#include "tcl_init.h"#include "cpu_interface.h"#include "sesl_expr.h"#include "sesl_lib.h"#include "symfile.h"#include "symbols.h"#include "sim_error.h"#include "symfile.h"#define OK 0#define ERROR 1#define NO 2static int symTclLoad(Tcl_Interp *interp, int argc, char *argv[]);static int symTclRead(Tcl_Interp *interp, int argc, char *argv[]);static int symTclType(Tcl_Interp *interp, int argc, char *argv[]);static int symTclSet(Tcl_Interp *interp, int argc, char *argv[]);static int symTclFind(Tcl_Interp *interp, int argc, char *argv[]);extern int SymDeref(ParseInfo *pip);static tclcmd symcmds[] = {{ "load", 4, symTclLoad, " load exeName path"},{ "read", 3, symTclRead, " read symexp"},{ "set", 4, symTclSet, " set symexp value"},{ "type", 3, symTclType, " type symexp"},{ "find", 4, symTclFind, " find execname addr"},{ NULL, 0, NULL, NULL}};static int readstr(Tcl_Interp *interp, ParseInfo *pip);void SymInit(Tcl_Interp *interp){ Tcl_CreateCommand(interp, "symbol", DispatchCmd, (ClientData) symcmds, NULL); SESL_Init(CPUPrint, CPUWarning, CPUError);}int symTclLoad(Tcl_Interp *interp, int argc, char *argv[]){ if (!SESL_LoadFile(argv[3], argv[2])) { return TCL_ERROR; } return TCL_OK;}/* * symTclRead */#ifdef SAME_ENDIAN#define GET_VALUE(_pi, _var, _type) \ if ((_pi).constant) { \ _var = (_type)(_pi).value; \ } else if ((_pi).internal) { \ _var = *(_type *)(_pi).value; \ } else { \ if (!CPUVec.GetMemory || \ CPUVec.GetMemory(CPUVec.CurrentCpuNum(), \ (_pi).value, sizeof(_type), (char*)&(_var)) \ != SUCCESS) { \ goto error; \ } \ }#else#define GET_VALUE(_pi, _var, _type) \ if ((_pi).constant) { \ _var = (_type)(_pi).value; \ } else if ((_pi).internal) { \ ASSERT (0); \ } else { \ if (!CPUVec.GetMemory || \ CPUVec.GetMemory(CPUVec.CurrentCpuNum(), \ (_pi).value, sizeof(_type), (char*)&(_var)) \ != SUCCESS) { \ goto error; \ } \ if (sizeof(_type)==2) _var = BE2HO_2(_var); \ if (sizeof(_type)==4) _var = BE2HO_4(_var); \ if (sizeof(_type)==8) _var = BE2HO_8(_var); \ }#endifint readstr(Tcl_Interp *interp, ParseInfo *pip){ Tcl_DString dstr; char c = '\0'; VA addr; int st; if (!pip->sym) { ASSERT(0); } st = SESL_GetTargetType(pip->sym); if ((st != SESL_TYPE_CHAR) && (st != SESL_TYPE_UCHAR)) { return NO; } GET_VALUE(*pip, addr, VA); Tcl_DStringInit(&dstr); while (1) { if (pip->internal) {#if defined(sgi) || defined(sun) c = *(char*)addr;#else ASSERT (0);#endif } else if (CPUVec.GetMemory(CPUVec.CurrentCpuNum(), addr, 1, (char *)&c) != SUCCESS) { return ERROR; } if (!c) { break; } Tcl_DStringAppend(&dstr, &c, 1); addr++; } Tcl_DStringResult(interp, &dstr); return OK;error: Tcl_DStringFree(&dstr); return ERROR;}int symTclRead(Tcl_Interp *interp, int argc, char *argv[]){ ParseInfo pi; uint64 value; char buf[128]; bzero((char*)&pi, sizeof(pi)); if (SymParse(argv[2], &pi) != SYM_OK) {#ifdef notdef if ((pi.str - argv[2]) < 128) { strncpy(buf, argv[2], pi.str - argv[2]); buf[pi.str - argv[2]] = '\0'; Tcl_AppendResult(interp, "\n ", buf, NULL); }#endif SESL_FreeSymbol(pi.sym); return TCL_ERROR; } pi.value = SESL_GetAddress(pi.sym); switch (SESL_GetType(pi.sym)) { case SESL_TYPE_LABEL: case SESL_TYPE_FUNC: { ASSERT(pi.constant); value = pi.value; PrintLLX(buf,value); break; } case SESL_TYPE_CHAR: { char c = 0; GET_VALUE(pi, c, char); sprintf(buf, "%d", (int)c); break; } case SESL_TYPE_UCHAR: { unsigned char c = 0; GET_VALUE(pi, c, unsigned char); sprintf(buf, "%u", (unsigned)c); break; } case SESL_TYPE_SHORT: { short s = 0; GET_VALUE(pi, s, short); sprintf(buf, "%d", (int)s); break; } case SESL_TYPE_USHORT: { unsigned short s = 0; GET_VALUE(pi, s, unsigned short); sprintf(buf, "%u", (unsigned)s); break; } case SESL_TYPE_INT: { int i = 0; GET_VALUE(pi, i, int); sprintf(buf, "%d", i); break; } case SESL_TYPE_LONG: { int32 i32 = 0; int64 i64 = 0; int size; switch ((size = (int)SESL_GetSize(pi.sym))) { case 4: GET_VALUE(pi, i32, int32); i64 = i32; break; case 8: GET_VALUE(pi, i64, int64); break; default: CPUWarning("SYMBOLS: Size of long is unsupported '%d' bytes (assume 4)\n", size); GET_VALUE(pi, i32, int32); i64 = i32; break; } PrintLLD(buf,i64); break; } case SESL_TYPE_LONGLONG: { int64 i = 0; GET_VALUE(pi, i, int64); PrintLLD(buf,(int64)i); break; } case SESL_TYPE_UINT:{ unsigned i = 0; GET_VALUE(pi, i, unsigned); sprintf(buf, "%u", i); break; } case SESL_TYPE_ULONG: { Reg i = 0; GET_VALUE(pi, i, Reg); PrintLLU(buf,(uint64)i); break; } case SESL_TYPE_ULONGLONG: { uint64 i = 0; GET_VALUE(pi, i, uint64); PrintLLU(buf,(uint64)i); break; } case SESL_TYPE_FLOAT: { uint f = 0; float *fptr = (float*)&f; GET_VALUE(pi, f, uint); sprintf(buf, "%f", *fptr); break; } case SESL_TYPE_DOUBLE: { int64 d = 0; double *dptr = (double *)&d; GET_VALUE(pi, d, int64); sprintf(buf, "%f", *dptr); break; } case SESL_TYPE_PTR: { int code = readstr(interp, &pi); if (code == OK) { return TCL_OK; } else if (code == NO) { uint32 p32 = 0; uint64 p64 = 0; int size; switch ((size = (int)SESL_GetSize(pi.sym))) { case 4: GET_VALUE(pi, p32, uint32); p64 = p32; break; case 8: GET_VALUE(pi, p64, uint64); break; default: CPUWarning("SYMBOLS: Size of ptr is unsupported '%d' bytes (assume 4)\n", size); GET_VALUE(pi, p32, uint32); p64 = p32; break; } PrintLLX(buf,p64); } else if (code == ERROR) { goto error; } break; } case SESL_TYPE_ARRAY: { int code; ASSERT(pi.constant); code = readstr(interp, &pi); if (code == OK) { return TCL_OK; } else if (code == NO) { value = pi.value; PrintLLX(buf, value); } else { goto error; } break; } case SESL_TYPE_STRUCT: case SESL_TYPE_UNION: case SESL_TYPE_ENUM: { /* XXX change */ ASSERT(!pi.constant); Tcl_AppendResult(interp, "type not impl yet", NULL); SESL_FreeSymbol(pi.sym); return TCL_ERROR; } case SESL_TYPE_UNKNOWN: default: SIM_DEBUG(('t', "offending type %s (%d)\n\r", SESL_GetTypeName(pi.sym), SESL_GetType(pi.sym))); CPUWarning("offending type %s (%d)\n\r", SESL_GetTypeName(pi.sym), SESL_GetType(pi.sym)); SESL_FreeSymbol(pi.sym); ASSERT(0); break; } Tcl_SetResult(interp, buf, TCL_VOLATILE); SESL_FreeSymbol(pi.sym); return TCL_OK;error: SIM_DEBUG(('t', "addr1 0x%x\n\r", pi.value)); Tcl_AppendResult(interp, "addr not mapped", NULL); SESL_FreeSymbol(pi.sym); return TCL_ERROR;}/* * symTclSet */#ifdef SAME_ENDIAN#define SET_VALUE(_pi, _var, _type) \ ASSERT(!(_pi).constant); \ ASSERT(!(_pi).internal); \ { _type x = _var; \ if (!CPUVec.PutMemory || \ CPUVec.PutMemory(CPUVec.CurrentCpuNum(), \ (_pi).value, sizeof(_type), (char*)&x) \ != SUCCESS) { \ goto error; \ } \ }#else#define SET_VALUE(_pi, _var, _type) \ ASSERT(!(_pi).constant); \ ASSERT(!(_pi).internal); \ { _type x = _var; \ if (sizeof(_type)==2) x = BE2HO_2(x); \ if (sizeof(_type)==4) x = BE2HO_4(x); \ if (sizeof(_type)==8) x = BE2HO_8(x); \ if (!CPUVec.PutMemory || \ CPUVec.PutMemory(CPUVec.CurrentCpuNum(), \ (_pi).value, sizeof(_type), (char*)&x) \ != SUCCESS) { \ goto error; \ } \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -