static void SignalReceived(int signum, siginfo_t * siginfo, void *context) { printf("\nProgram received signal %d (%s)\n", signum, sys_siglist[signum]); // These two lines get the value of RIP register at time of crash, i.e. // address of instruction that faulted const int rip_index = 16; const int rbp_index = 10; void *rip = (void *)((struct ucontext *)context)->uc_mcontext.gregs[rip_index]; void *rbp = (void *)((struct ucontext *)context)->uc_mcontext.gregs[rbp_index]; // this starter code only prints the symbol addr // should eventually print [%p] %s (+0x%x) with addr, name, offset arguments char ret_addr[9] = {0x0}; sprintf(ret_addr, "0x%llx", (long long int)rip); long long int offset; char* symbol = (char*)SearchSymbol(ret_addr, &offset); printf("Faulting instruction at [%018lx] %s (+0x%llx)\n", (uint64_t)rip, symbol, offset); do{ memset(ret_addr, 0x00, 9); sprintf(ret_addr, "0x%llx", (long long int) *((uint64_t*)rbp+1)); //printf("ret_addr [%s]\n", ret_addr); symbol = SearchSymbol(ret_addr, &offset); if(symbol == NULL) { printf("[%018lx] %s (+0x%llx)\n", (uint64_t)*((uint64_t*)rbp+1), "Unknown", (long long unsigned int)0); break; } printf("[%018lx] %s (+0x%llx)\n", (uint64_t)*((uint64_t*)rbp+1), symbol, offset); rbp = (void*)*((uint64_t*)rbp); } while( symbol == NULL || strcmp(symbol, "main") != 0); exit(0); // terminate process }
// Add symbol with relative address to last module, // pMT points to the Module Table int AddSymbol(MODULE_t * MT, char * sym_name, int addr) { if (MT == NULL) return -1; // for safety purpose SYMBOL_t *pSym = SearchSymbol(MT, sym_name); if (pSym) // already defined? { pSym->flag |= MULTIDEF; return 0; } MODULE_t * pMod = &MT[mod_count-1]; pSym = &(pMod->Def[pMod->def_count++]); pSym->addr = addr; // initialize new symbol strcpy(pSym->symbol, sym_name); pSym->flag = 0x00; return 0; }
// Pass Two void PassTwo(FILE* pFile, MODULE_t * MT) { if (!pFile) { // file pointer invalid? printf("File access error, exit.\n"); return; } printf("Memory Map\n"); rewind(pFile); // back to the beginning char instr_type, * instr; int addr = 0; int def_count = 0; int oprand, errno; char *sym; SYMBOL_t *pSym; int i, j; for (i=0;i<ModuleTableSize();i++) { def_count = atoi(GetToken(pFile,NULL,NULL)); SkipToken(pFile, def_count*2+1+MT[i].use_count+1); for (j=0; j<MT[i].size; j++) { instr_type = GetToken(pFile, NULL, NULL)[0]; instr = GetToken(pFile, NULL, NULL); if (strlen(instr) > 4) { if (instr_type == 'I') PrintInstr(addr, '9', 999, INSTR_ILLEGAL_I, NULL); else PrintInstr(addr, '9', 999, INSTR_ILLEGAL_OP, NULL); } else { oprand = atoi(instr+1); // get oprand regardless if 'I' type instruction errno = INSTR_NO_ERROR; sym = NULL; switch (instr_type) { case 'I': break; case 'A': if (oprand > 511) { oprand = 0; errno = INSTR_LARGE_A; } break; case 'R': if (oprand > MT[i].size) { oprand = MT[i].addr; errno = INSTR_LARGE_R; } else oprand += MT[i].addr; break; case 'E': if (oprand < MT[i].use_count) { MT[i].Use[oprand].flag |= REFERRED; sym = MT[i].Use[oprand].symbol; pSym = SearchSymbol(MT, sym); if (pSym == NULL) { oprand = 0; errno = INSTR_NO_DEF; } else { pSym->flag |= REFERRED; oprand = pSym->addr; } } else { errno = INSTR_LARGE_E; } break; } // switch PrintInstr(addr, instr[0], oprand, errno, sym); } // if-else addr++; // finished one instruction, increment addr } // for each instruction UseListCheck(MT, i); } // for each module RefCheck(MT); }