📄 symfile.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. * */ /***************************************************************** * * $Author: bosch $ * $Date *****************************************************************/#include <sys/types.h>#include <sys/stat.h>#include <sys/mman.h>#include <netinet/in.h>#ifdef __alpha#define _LANGUAGE_C#define _MIPS_SZINT 32/* #include "elf-sgi.h" */#endif#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include "file_formats.h"#include "symbols.h"#include "simutil.h"#include "symfile.h"#include "assoctab.h"#include "tcl_init.h"#include "sim_error.h"#define MIPS_MDEBUG ".mdebug"#define ADDR_IN_RANGE(_addr, _lo, _hi) (((uint)(_addr) >= (uint)(_lo)) && ((uint)(_addr) < (uint)(_hi)))/* * types */typedef struct Execfile { ATHeader head; AssocTab *srcs; AssocTab *globals; AssocTab *gStructs; char *fileStart; pHDRR symHdr; /* easy access */ pFDR pfds; /* easy access */ pSYMR syms; /* easy access */ pAUXU aux; /* easy access */ pEXTR extrs; /* easy access */ pRFDT fit; /* easy access */} Execfile;typedef struct Srcfile { ATHeader head; int num; FDR pfd; /* easy access */ pFDR pfdPtr;} Srcfile;typedef struct Global { ATHeader head; int isym; int filenum;} Global;/* * variables */static AssocTab *exectab = NULL;static SymbInfo sitab[] = { {0, 0, 0, 0}, /* 0 tNil */ {0, 1, 1, 1}, /* 1 tChar */ {0, 1, 1, 1}, /* 2 tUChar */ {0, 1, 1, 1}, /* 3 tShort */ {0, 1, 1, 1}, /* 4 tUShort */ {0, 1, 1, 1}, /* 5 tInt */ {0, 1, 1, 1}, /* 6 tUInt */ {0, 1, 1, 1}, /* 7 tLong */ {0, 1, 1, 1}, /* 8 tULong */ {0, 1, 1, 1}, /* 9 tFloat */ {0, 1, 1, 1}, /* 10 tDouble */ {0, 0, 1, 1}, /* 11 tStruct */ {0, 0, 1, 1}, /* 12 tUnion */ {0, 0, 1, 1}, /* 13 tEnum */ {0, 0, 1, 1}, /* 14 tTypedef */ {0, 0, 1, 1}, /* 15 tPtr */ {0, 0, 1, 1}, /* 16 tArray */ {0, 1, 0, 1}, /* 17 tLabel */ {1, 0, 0, 1}, /* 18 tProc */ {1, 1, 0, 0}, /* 19 tStructDef */ {1, 1, 0, 0}, /* 20 tUnionDef */ {1, 1, 0, 0}, /* 21 tEnumDef */ {0, 1, 0, 0}, /* 22 tAddr */ {1, 1, 0, 0}, /* 23 tFile */ {0, 1, 0, 0}, /* 24 tEnd */ {1, 1, 0, 0}, /* 25 tBlock */ {0, 0, 0, 0}, /* 26 tTypedefDef */ {0, 0, 0, 0}, /* 27 tIndirect */};SymbInfo *SymInfo = sitab;/* * functions */static void FillIn(Symb *sym, Execfile *exec, int isym, int filenum);static void FillInBasicType(Symb *sym, int index, pSYMR psym);extern void *Simrmt_mmap(void *addr, size_t len, int prot, int flags, char* pathname, off_t off);static void CopySYMR (pSYMR mapped,pSYMR copy);static void CopyFDR (pFDR mapped,pFDR copy);static void CopyTIR (pTIR mapped,pTIR copy);static void CopyRNDXR(pRNDXR mapped,pRNDXR copy);/* * SymLoad */int SymLoad(char *pathname, char *execname){ char *filename; struct stat statbuf; int fd, retval; char *fp; Execfile *exec; Srcfile *src; Global *global; ATHeader *dummy; FILHDR *fileHdr; Elf32_Ehdr *ehdr; pFDR pfd; pEXTR extr; int i; if (!exectab) { exectab = AssocTabCreate(); } /* check if execname already used */ if (AssocTabLookup(exectab, execname, &dummy) == AT_OK) { SymReportError("execname already taken \"", execname, "\"", NULL); return SYM_ERROR; } if (!(filename = SearchForFile(pathname))) { SymReportError("no such file \"", pathname, "\"", NULL); return SYM_ERROR; } if (strchr(filename, ':')) { /* remote */#if defined(SIMALPHA) ASSERT(0); fp = 0;#else fp = Simrmt_mmap(NULL, 0, PROT_READ, MAP_SHARED, filename, 0);#endif } else { /* local */ fd = open(filename, O_RDONLY, 0); if (fd < 0) { SymReportError("couldn't open \"", filename, "\"", NULL); return SYM_ERROR; } retval = fstat(fd, &statbuf); if (retval < 0) { SymReportError("couldn't stat \"", filename, "\"", NULL); return SYM_ERROR; } #ifdef __alpha fp = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED|MAP_FILE, fd, 0);#else fp = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);#endif if (fp == (char*)-1) { SymReportError("couldn't mmap \"", filename, "\"", NULL); return SYM_ERROR; } close(fd); } fileHdr = (FILHDR*)fp; ehdr = (Elf32_Ehdr*)fp; exec = (Execfile*)malloc(sizeof(Execfile)); exec->head.label = SaveString(execname); exec->fileStart = fp; if (ISCOFF(BE2HO_2(fileHdr->f_magic))) { if ((BE2HO_4(fileHdr->f_nsyms) == 0) || (BE2HO_4(fileHdr->f_symptr) == 0) || (BE2HO_4(fileHdr->f_symptr) == -1)) { SymReportError("did not find symbol table in \"", filename, "\"", NULL); return SYM_ERROR; } exec->symHdr = (pHDRR)(fp + BE2HO_4(fileHdr->f_symptr)); } else if (IS_ELF(*ehdr)) { Elf32_Shdr *shdr = (Elf32_Shdr *)(fp + BE2HO_4(ehdr->e_shoff)); char *strs = (char *)fp + BE2HO_4(shdr[BE2HO_2(ehdr->e_shstrndx)].sh_offset); if ( BE2HO_1(ehdr->e_ident[EI_CLASS]) != ELFCLASS32 ) { /* should clean up mmapped stuff */#ifdef DWARF2 /* we add special entry with null fileStart to indicate dwarf */ exec->fileStart = 0; if (AssocTabEnter(exectab, (ATHeader*)exec) != AT_OK) { ASSERT(0); } /* now call dwarf2 64-bit code */ return Dwarf_SymLoad(pathname, execname);#else /* don't fully support 64 bit elf files here yet */ SymReportError("elf64 symtab format in \"", filename, "\"", NULL); return SYM_ERROR;#endif } for (i=0; i<BE2HO_2(ehdr->e_shnum); i++, shdr++) { if (!strcmp(strs + BE2HO_4(shdr->sh_name), MIPS_MDEBUG)) { exec->symHdr = (pHDRR)(fp + BE2HO_4(shdr->sh_offset)); break; } } if (i == ehdr->e_shnum) { SymReportError("did not find symbol table in \"", filename, "\"", NULL); return SYM_ERROR; } } else { SymReportError("architecture of \"", filename, "\" not known", NULL); return SYM_ERROR; } exec->pfds = (pFDR) (fp + BE2HO_4(exec->symHdr->cbFdOffset)); exec->syms = (pSYMR) (fp + BE2HO_4(exec->symHdr->cbSymOffset)); exec->aux = (pAUXU) (fp + BE2HO_4(exec->symHdr->cbAuxOffset)); exec->extrs = (pEXTR)(fp + BE2HO_4(exec->symHdr->cbExtOffset)); exec->fit = (pRFDT) (fp + BE2HO_4(exec->symHdr->cbRfdOffset)); exec->srcs = AssocTabCreate(); exec->globals = AssocTabCreate(); exec->gStructs = AssocTabCreate(); pfd = (pFDR)(fp + BE2HO_4(exec->symHdr->cbFdOffset)); for (i=0; i<BE2HO_4(exec->symHdr->ifdMax); i++, pfd++) { if (AssocTabLookup(exec->srcs, StripPath(fp + BE2HO_4(pfd->issBase) + BE2HO_4(exec->symHdr->cbSsOffset) + BE2HO_4(pfd->rss)), NULL) == AT_OK) { /* nothing */ } else { src = (Srcfile*)malloc(sizeof(Srcfile)); src->num = i; src->pfdPtr = pfd; CopyFDR(pfd,&src->pfd); src->head.label = StripPath(fp + src->pfd.issBase + BE2HO_4(exec->symHdr->cbSsOffset) + src->pfd.rss); if (AssocTabEnter(exec->srcs, (ATHeader*)src) != AT_OK) { ASSERT(0); } if (src->pfd.fMerge) { /* * this is a header - lets scan it for structs. * even though structs are not global we are going to do this * as a heuristic */ Symb symb; FillIn(&symb, exec, src->pfd.isymBase, i); if (SymIn(&symb) != SYM_OK) { ASSERT(0); return SYM_ERROR; } while (symb.type[symb.nextt] != tEnd) { if ((symb.type[symb.nextt] == tStructDef) || (symb.type[symb.nextt] == tUnionDef) || (symb.type[symb.nextt] == tEnumDef)) { global = (Global*)malloc(sizeof(Global)); global->head.label = symb.name; global->isym = symb.isym; global->filenum = symb.filenum; if (AssocTabEnter(exec->gStructs, (ATHeader*)global) != AT_OK) { /* 2 structs with the same name, ignore */ } } if (SymNext(&symb) != SYM_OK) { ASSERT(0); return SYM_ERROR; } } } } } extr = exec->extrs; for (i=0; i<BE2HO_4(exec->symHdr->iextMax); i++, extr++) { global = (Global*)malloc(sizeof(Global)); global->head.label = fp + BE2HO_4(exec->symHdr->cbSsExtOffset) + BE2HO_4(extr->asym.iss); global->isym = i; global->filenum = -1; if (AssocTabEnter(exec->globals, (ATHeader*)global) != AT_OK) { /* 2 globals with the same name */ ASSERT(0); } } if (AssocTabEnter(exectab, (ATHeader*)exec) != AT_OK) { ASSERT(0); } return SYM_OK;}/* * SymAddr2Symbol */int SymAddr2Symbol(char *execname, int addr, Symb *sym){ Execfile *exec = NULL; SYMR symr; pEXTR extr; int i; int best, bestFile, bestVal; int filenum; if (!exectab) { exectab = AssocTabCreate(); } if (AssocTabLookup(exectab, execname, (ATHeader**)&exec) != AT_OK) { SymReportError("no exec named \"", execname, "\"", NULL); return SYM_ERROR; }#ifdef DWARF2 ASSERT (0);#endif#ifdef DWARF2 if( exec->fileStart == 0 ) { /* hack to indicate must be dwarf stuff */ return Dwarf_SymAddr2Symbol(execname, addr, sym); }#endif filenum = -1; bestVal = 0; best = -1; bestFile = -1; extr = exec->extrs; for (i=0; i<BE2HO_4(exec->symHdr->iextMax); i++, extr++) { if (((uint)BE2HO_4(extr->asym.value) > (uint)bestVal) && ((uint)BE2HO_4(extr->asym.value) <= (uint)addr)) { best = i; bestFile = filenum; bestVal =BE2HO_4(extr->asym.value); } } CopySYMR(exec->syms,&symr); for (i=0; i<BE2HO_4(exec->symHdr->isymMax); i++) { CopySYMR(exec->syms+i,&symr); if (symr.st == stFile) { filenum++; } if (symr.st == stLabel) { continue; } if ((symr.value > (uint)bestVal) && (symr.value <= (uint)addr)) { best = i; bestFile = filenum; bestVal = symr.value; } } FillIn(sym, exec, best, bestFile); return SYM_OK;}/* * SymLine2Addr */int SymLine2Addr(char *execname, char *srcfile, int line, Symb *sym){ Execfile *exec = NULL; Srcfile *src = NULL; PDR *pdr; char *base; int bestaddr, p; if (!exectab) { exectab = AssocTabCreate(); } if (AssocTabLookup(exectab, execname, (ATHeader**)&exec) != AT_OK) { SymReportError("no exec named \"", execname, "\"", NULL); return SYM_ERROR; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -