📄 symtcl.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 "symexpr.h"#include "symfile.h"#include "symbols.h"#include "sim_error.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[]);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);}int symTclLoad(Tcl_Interp *interp, int argc, char *argv[]){#ifdef DWARF2__not if (Dwarf_SymLoad(argv[3], argv[2]) != SYM_OK) { return TCL_ERROR; }#else if (SymLoad(argv[3], argv[2]) != SYM_OK) { return TCL_ERROR; }#endif return TCL_OK;}/* * symTclRead */#ifdef HOST_BIG_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; \ } \ }#endif#ifdef HOST_LITTLE_ENDIAN#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; Symb tmp = pip->sym; int st; if (SymSubtype(&tmp, SYM_RESOLVE) != SYM_OK) { ASSERT(0); } st = SymType(&tmp, SYM_RESOLVE); if ((st != tChar) && (st != tUChar)) { 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; char buf[128]; 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 return TCL_ERROR; } switch (SymType(&pi.sym, SYM_RESOLVE)) { case tLabel: case tProc: case tAddr: { ASSERT(pi.constant); PrintLLX(buf,(uint64)pi.value); break; } case tChar: { char c = 0; GET_VALUE(pi, c, char); sprintf(buf, "%d", (int)c); break; } case tUChar: { unsigned char c = 0; GET_VALUE(pi, c, unsigned char); sprintf(buf, "%u", (unsigned)c); break; } case tShort: { short s = 0; GET_VALUE(pi, s, short); sprintf(buf, "%d", (int)s); break; } case tUShort: { unsigned short s = 0; GET_VALUE(pi, s, unsigned short); sprintf(buf, "%u", (unsigned)s); break; } case tInt: { int i = 0; GET_VALUE(pi, i, int); sprintf(buf, "%d", i); break; } case tLong: { /* * XXX Reg should be a long in the target system */ Reg_s i = 0; GET_VALUE(pi, i, Reg_s); PrintLLD(buf,(int64)i); break; } case tUInt:{ unsigned i = 0; GET_VALUE(pi, i, unsigned); sprintf(buf, "%u", i); break; } case tULong: { Reg i = 0; GET_VALUE(pi, i, Reg); PrintLLU(buf,(uint64)i); break; } case tFloat: { uint f = 0; float *fptr = (float*)&f; GET_VALUE(pi, f, uint); sprintf(buf, "%f", *fptr); break; } case tDouble: { int64 d = 0; double *dptr = (double *)&d; GET_VALUE(pi, d, int64); sprintf(buf, "%f", *dptr); break; } case tPtr: { int code = readstr(interp, &pi); if (code == OK) { return TCL_OK; } else if (code == NO) { Reg p = 0; GET_VALUE(pi, p, Reg); PrintLLX(buf,(uint64)p); } else if (code == ERROR) { goto error; } break; } case tArray: { int code; ASSERT(pi.constant); code = readstr(interp, &pi); if (code == OK) { return TCL_OK; } else if (code == NO) { PrintLLX(buf, (uint64)pi.value); } else { goto error; } break; } case tStruct: case tUnion: case tEnum: { /* XXX change */ ASSERT(!pi.constant); Tcl_AppendResult(interp, "type not impl yet", NULL); return TCL_ERROR; } case tNil: default: SIM_DEBUG(('t', "offending type %d\n\r", SymType(&pi.sym, SYM_RESOLVE))); CPUWarning("offending type %d\n\r", SymType(&pi.sym, SYM_RESOLVE)); ASSERT(0); break; } Tcl_SetResult(interp, buf, TCL_VOLATILE); return TCL_OK;error: SIM_DEBUG(('t', "addr1 0x%x\n\r", pi.value)); Tcl_AppendResult(interp, "addr not mapped", NULL); return TCL_ERROR;}/* * symTclSet */#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; \ } \ }int writestr(Tcl_Interp *interp, ParseInfo *pip, char *str){ int addr; Symb tmp = pip->sym; int st; if (SymSubtype(&tmp, 0) != SYM_OK) { ASSERT(0); } st = SymType(&tmp, SYM_RESOLVE); if ((st != tChar) && (st != tUChar)) { return NO; } GET_VALUE(*pip, addr, int); while (1) { if (CPUVec.PutMemory(CPUVec.CurrentCpuNum(), addr, 1, (char *)str) != SUCCESS) { return ERROR; } if (*str == '\0') break; str++; addr++; } return OK;error: return ERROR;}int symTclSet(Tcl_Interp *interp, int argc, char *argv[]){ ParseInfo pi; if (SymParse(argv[2], &pi) != SYM_OK) { return TCL_ERROR; } if (pi.constant) { Tcl_AppendResult(interp, "cannot set this type, its a constant", NULL); return TCL_ERROR; } else if (pi.internal) { Tcl_AppendResult(interp, "can't write to simulator memory (?)", NULL); return TCL_ERROR; } switch (SymType(&pi.sym, SYM_RESOLVE)) { case tChar: case tUChar: { char c = 0; int i = 0; if (sscanf(argv[3], "%d", &i) != 1) { Tcl_AppendResult(interp, "expected an int", NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -