bool PCLibraryState::cacheLibraryRanges(Library::ptr lib) { std::string filename = lib->getName(); Address base = lib->getLoadAddress(); SymbolReaderFactory *fact = getDefaultSymbolReader(); SymReader *reader = fact->openSymbolReader(filename); if (!reader) { sw_printf("[%s:%u] - Error could not open expected file %s\n", FILE__, __LINE__, filename.c_str()); return false; } int num_segments = reader->numSegments(); for (int i=0; i<num_segments; i++) { SymSegment segment; reader->getSegment(i, segment); if (segment.type != 1) continue; Address segment_start = segment.mem_addr + base; Address segment_end = segment_start + segment.mem_size; loadedLibs.insert(segment_start, segment_end, makeCache(LibAddrPair(lib->getName(), lib->getLoadAddress()), lib)); } return true; }
SymReader *LibraryWrapper::getLibrary(std::string filename) { std::map<std::string, SymReader *>::iterator i = libs.file_map.find(filename); if (i != libs.file_map.end()) { return i->second; } SymbolReaderFactory *fact = Walker::getSymbolReader(); SymReader *reader = fact->openSymbolReader(filename); if (!reader) return NULL; libs.file_map[filename] = reader; return reader; }
void SigHandlerStepperImpl::registerStepperGroup(StepperGroup *group) { sw_printf("[%s:%u] - Begin SigHandlerStepperImpl::registerStepperGroup\n", FILE__, __LINE__); ProcessState *ps = getProcessState(); assert(ps); LibraryState *libs = getProcessState()->getLibraryTracker(); if (!libs) { sw_printf("[%s:%u] - Custom library tracker. Don't know how to" " to get libc\n", FILE__, __LINE__); return; } SymbolReaderFactory *fact = Walker::getSymbolReader(); if (!fact) { sw_printf("[%s:%u] - Failed to get symbol reader\n", FILE__, __LINE__); return; } sw_printf("[%s:%u] - Got lib tracker and sym reader OK, checking for __restore_rt...\n", FILE__, __LINE__); if (!init_libc) { /** * Get __restore_rt out of libc **/ sw_printf("[%s:%u] - Getting __restore_rt from libc\n", FILE__, __LINE__); LibAddrPair libc_addr; Dyninst::SymReader *libc = NULL; Symbol_t libc_restore; bool result = libs->getLibc(libc_addr); if (!result) { sw_printf("[%s:%u] - Unable to find libc, not registering restore_rt" "tracker.\n", FILE__, __LINE__); } if (!init_libc) { if (result) { init_libc = true; libc = fact->openSymbolReader(libc_addr.first); if (!libc) { sw_printf("[%s:%u] - Unable to open libc, not registering restore_rt\n", FILE__, __LINE__); } } if (result && libc) { init_libc = true; libc_restore = libc->getSymbolByName("__restore_rt"); if (!libc->isValidSymbol(libc_restore)) { sw_printf("[%s:%u] - Unable to find restore_rt in libc\n", FILE__, __LINE__); } else { Dyninst::Address start = libc->getSymbolOffset(libc_restore) + libc_addr.second; Dyninst::Address end = libc->getSymbolSize(libc_restore) + start; if (start == end) end = start + 16; //Estimate--annoying sw_printf("[%s:%u] - Registering libc restore_rt as at %lx to %lx\n", FILE__, __LINE__, start, end); group->addStepper(parent_stepper, start, end); } } } } if (!init_libthread) { /** * Get __restore_rt out of libpthread **/ sw_printf("[%s:%u] - Getting __restore_rt out of libpthread\n", FILE__, __LINE__); LibAddrPair libpthread_addr; Dyninst::SymReader *libpthread = NULL; Symbol_t libpthread_restore; bool result = libs->getLibthread(libpthread_addr); if (!result) { sw_printf("[%s:%u] - Unable to find libpthread, not registering restore_rt" "pthread tracker.\n", FILE__, __LINE__); } if (result) { libpthread = fact->openSymbolReader(libpthread_addr.first); if (!libpthread) { sw_printf("[%s:%u] - Unable to open libc, not registering restore_rt\n", FILE__, __LINE__); } init_libthread = true; } if (libpthread) { libpthread_restore = libpthread->getSymbolByName("__restore_rt"); if (!libpthread->isValidSymbol(libpthread_restore)) { sw_printf("[%s:%u] - Unable to find restore_rt in libpthread\n", FILE__, __LINE__); } else { Dyninst::Address start = libpthread->getSymbolOffset(libpthread_restore) + libpthread_addr.second; Dyninst::Address end = libpthread->getSymbolSize(libpthread_restore) + start; if (start == end) end = start + 16; //Estimate--annoying sw_printf("[%s:%u] - Registering libpthread restore_rt as at %lx to %lx\n", FILE__, __LINE__, start, end); group->addStepper(parent_stepper, start, end); } } } /** * Get symbols out of vsyscall page **/ sw_printf("[%s:%u] - Getting vsyscall page symbols\n", FILE__, __LINE__); vsys_info *vsyscall = getVsysInfo(ps); if (!vsyscall) { #if !defined(arch_x86_64) sw_printf("[%s:%u] - Odd. Couldn't find vsyscall page. Signal handler" " stepping may not work\n", FILE__, __LINE__); #endif } else { SymReader *vsys_syms = vsyscall->syms; if (!vsys_syms) { sw_printf("[%s:%u] - Vsyscall page wasn't parsed\n", FILE__, __LINE__); } else { for (unsigned i=0; i<NUM_VSYS_SIGRETURNS; i++) { Symbol_t sym; sym = vsys_syms->getSymbolByName(vsys_sigreturns[i]); if (!vsys_syms->isValidSymbol(sym)) continue; Dyninst::Offset offset = vsys_syms->getSymbolOffset(sym); Dyninst::Address addr; if (offset < vsyscall->start) addr = offset + vsyscall->start; else addr = offset; unsigned long size = vsys_syms->getSymbolSize(sym); if (!size) size = ps->getAddressWidth(); group->addStepper(parent_stepper, addr, addr + size); } } } }
vsys_info *Dyninst::Stackwalker::getVsysInfo(ProcessState *ps) { #if defined(arch_x86_64) || defined(arch_aarch64) if (ps->getAddressWidth() == 8) return NULL; #endif static std::map<ProcessState *, vsys_info *> vsysmap; vsys_info *ret = NULL; Address start, end; char *buffer = NULL; SymReader *reader = NULL; SymbolReaderFactory *fact = NULL; bool result; std::stringstream ss; std::map<ProcessState *, vsys_info *>::iterator i = vsysmap.find(ps); if (i != vsysmap.end()) return i->second; AuxvParser *parser = AuxvParser::createAuxvParser(ps->getProcessId(), ps->getAddressWidth()); if (!parser) { sw_printf("[%s:%u] - Unable to parse auxv for %d\n", FILE__, __LINE__, ps->getProcessId()); goto done; } start = parser->getVsyscallBase(); end = parser->getVsyscallEnd(); sw_printf("[%s:%u] - Found vsyscall over range %lx to %lx\n", FILE__, __LINE__, start, end); parser->deleteAuxvParser(); if (!start || !end || end == start) { sw_printf("[%s:%u] - Error collecting vsyscall base and end\n", FILE__, __LINE__); goto done; } ret = new vsys_info(); assert(ret); ret->start = start; ret->end = end; buffer = (char *) malloc(end - start); assert(buffer); result = ps->readMem(buffer, start, end - start); if (!result) { sw_printf("[%s:%u] - Error reading vsys memory\n", FILE__, __LINE__); goto done; } ret->vsys_mem = buffer; fact = Walker::getSymbolReader(); if (!fact) { sw_printf("[%s:%u] - No symbol reading capability\n", FILE__, __LINE__); goto done; } reader = fact->openSymbolReader(buffer, end - start); if (!reader) { sw_printf("[%s:%u] - Error reading symbol info\n"); goto done; } ret->syms = reader; ss << "[vsyscall-" << ps->getProcessId() << "]"; ret->name = ss.str(); LibraryWrapper::registerLibrary(reader, ret->name); done: vsysmap[ps] = ret; return ret; }
void BottomOfStackStepperImpl::initialize() { ProcessState *proc = walker->getProcessState(); assert(proc); sw_printf("[%s:%u] - Initializing BottomOfStackStepper\n", FILE__, __LINE__); LibraryState *libs = proc->getLibraryTracker(); if (!libs) { sw_printf("[%s:%u] - Error initing StackBottom. No library state for process.\n", FILE__, __LINE__); return; } SymbolReaderFactory *fact = Walker::getSymbolReader(); if (!fact) { sw_printf("[%s:%u] - Failed to get symbol reader\n"); return; } if (!aout_init) { LibAddrPair aout_addr; SymReader *aout = NULL; Symbol_t start_sym; bool result = libs->getAOut(aout_addr); if (result) { aout = fact->openSymbolReader(aout_addr.first); aout_init = true; } if (aout) { start_sym = aout->getSymbolByName(START_FUNC_NAME); if (aout->isValidSymbol(start_sym)) { Dyninst::Address start = aout->getSymbolOffset(start_sym)+aout_addr.second; Dyninst::Address end = aout->getSymbolSize(start_sym) + start; if (start == end) { sw_printf("[%s:%u] - %s symbol has 0 length, using length of %lu\n", FILE__, __LINE__, START_FUNC_NAME, START_HEURISTIC_LENGTH); end = start + START_HEURISTIC_LENGTH; } sw_printf("[%s:%u] - Bottom stepper taking %lx to %lx for start\n", FILE__, __LINE__, start, end); ra_stack_tops.push_back(std::pair<Address, Address>(start, end)); } } } if (!libthread_init) { LibAddrPair libthread_addr; SymReader *libthread = NULL; Symbol_t clone_sym, startthread_sym; bool result = libs->getLibthread(libthread_addr); if (result) { libthread = fact->openSymbolReader(libthread_addr.first); libthread_init = true; } if (libthread) { clone_sym = libthread->getSymbolByName(CLONE_FUNC_NAME); if (libthread->isValidSymbol(clone_sym)) { Dyninst::Address start = libthread->getSymbolOffset(clone_sym) + libthread_addr.second; Dyninst::Address end = libthread->getSymbolSize(clone_sym) + start; sw_printf("[%s:%u] - Bottom stepper taking %lx to %lx for clone\n", FILE__, __LINE__, start, end); ra_stack_tops.push_back(std::pair<Address, Address>(start, end)); } startthread_sym = libthread->getSymbolByName(START_THREAD_FUNC_NAME); if (libthread->isValidSymbol(startthread_sym)) { Dyninst::Address start = libthread->getSymbolOffset(startthread_sym) + libthread_addr.second; Dyninst::Address end = libthread->getSymbolSize(startthread_sym) + start; sw_printf("[%s:%u] - Bottom stepper taking %lx to %lx for start_thread\n", FILE__, __LINE__, start, end); ra_stack_tops.push_back(std::pair<Address, Address>(start, end)); } } } }