bool ElfRelocations::ApplyRelaRelocs(const ELF::Rela* rela, size_t rela_count, const ElfSymbols* symbols, SymbolResolver* resolver, Error* error) { RLOG("%s: rela=%p rela_count=%d\n", __FUNCTION__, rela, rela_count); if (!rela) return true; for (size_t rel_n = 0; rel_n < rela_count; rela++, rel_n++) { const ELF::Word rel_type = ELF_R_TYPE(rela->r_info); const ELF::Word rel_symbol = ELF_R_SYM(rela->r_info); ELF::Addr sym_addr = 0; ELF::Addr reloc = static_cast<ELF::Addr>(rela->r_offset + load_bias_); RLOG(" %d/%d reloc=%p offset=%p type=%d symbol=%d\n", rel_n + 1, rela_count, reloc, rela->r_offset, rel_type, rel_symbol); if (rel_type == 0) continue; bool resolved = false; // If this is a symbolic relocation, compute the symbol's address. if (__builtin_expect(rel_symbol != 0, 0)) { resolved = ResolveSymbol(rel_type, rel_symbol, symbols, resolver, reloc, &sym_addr, error); } if (!ApplyRelaReloc(rela, sym_addr, resolved, error)) return false; } return true; }
bool ElfRelocations::ApplyRelaReloc(const ELF::Rela* rela, const ElfSymbols* symbols, SymbolResolver* resolver, Error* error) { const ELF::Word rel_type = ELF_R_TYPE(rela->r_info); const ELF::Word rel_symbol = ELF_R_SYM(rela->r_info); ELF::Addr sym_addr = 0; ELF::Addr reloc = static_cast<ELF::Addr>(rela->r_offset + load_bias_); RLOG(" reloc=%p offset=%p type=%d symbol=%d\n", reloc, rela->r_offset, rel_type, rel_symbol); if (rel_type == 0) return true; bool resolved = false; // If this is a symbolic relocation, compute the symbol's address. if (__builtin_expect(rel_symbol != 0, 0)) { if (!ResolveSymbol(rel_type, rel_symbol, symbols, resolver, reloc, &sym_addr, error)) { return false; } resolved = true; } return ApplyResolvedRelaReloc(rela, sym_addr, resolved, error); }
void AFXAPI AfxDumpStack(DWORD dwTarget /* = AFX_STACK_DUMP_TARGET_DEFAULT */) { CTraceClipboardData clipboardData(dwTarget); clipboardData.SendOut("=== begin AfxDumpStack output ===\r\n"); CDWordArray adwAddress; HANDLE hProcess = ::GetCurrentProcess(); if (SymInitialize(hProcess, NULL, FALSE)) { // force undecorated names to get params DWORD dw = SymGetOptions(); dw &= ~SYMOPT_UNDNAME; SymSetOptions(dw); HANDLE hThread = ::GetCurrentThread(); CONTEXT threadContext; threadContext.ContextFlags = CONTEXT_FULL; if (::GetThreadContext(hThread, &threadContext)) { STACKFRAME stackFrame; memset(&stackFrame, 0, sizeof(stackFrame)); stackFrame.AddrPC.Mode = AddrModeFlat; DWORD dwMachType; #if defined(_M_IX86) dwMachType = IMAGE_FILE_MACHINE_I386; // program counter, stack pointer, and frame pointer stackFrame.AddrPC.Offset = threadContext.Eip; stackFrame.AddrStack.Offset = threadContext.Esp; stackFrame.AddrStack.Mode = AddrModeFlat; stackFrame.AddrFrame.Offset = threadContext.Ebp; stackFrame.AddrFrame.Mode = AddrModeFlat; #elif defined(_M_MRX000) // only program counter dwMachType = IMAGE_FILE_MACHINE_R4000; stackFrame.AddrPC. Offset = treadContext.Fir; #elif defined(_M_ALPHA) // only program counter dwMachType = IMAGE_FILE_MACHINE_ALPHA; stackFrame.AddrPC.Offset = (unsigned long) threadContext.Fir; #elif defined(_M_PPC) // only program counter dwMachType = IMAGE_FILE_MACHINE_POWERPC; stackFrame.AddrPC.Offset = threadContext.Iar; #elif #error("Unknown Target Machine"); #endif adwAddress.SetSize(0, 16); int nFrame; for (nFrame = 0; nFrame < 1024; nFrame++) { if (!StackWalk(dwMachType, hProcess, hProcess, &stackFrame, &threadContext, NULL, FunctionTableAccess, GetModuleBase, NULL)) { break; } adwAddress.SetAtGrow(nFrame, stackFrame.AddrPC.Offset); } } } else { DWORD dw = GetLastError(); char sz[100]; wsprintfA(sz, "AfxDumpStack Error: IMAGEHLP.DLL wasn't found. " "GetLastError() returned 0x%8.8X\r\n", dw); clipboardData.SendOut(sz); } // dump it out now int nAddress; int cAddresses = adwAddress.GetSize(); for (nAddress = 0; nAddress < cAddresses; nAddress++) { SYMBOL_INFO info; DWORD dwAddress = adwAddress[nAddress]; char sz[20]; wsprintfA(sz, "%8.8X: ", dwAddress); clipboardData.SendOut(sz); if (ResolveSymbol(hProcess, dwAddress, info)) { clipboardData.SendOut(info.szModule); clipboardData.SendOut(info.szSymbol); } else clipboardData.SendOut("symbol not found"); clipboardData.SendOut("\r\n"); } clipboardData.SendOut("=== end AfxDumpStack() output ===\r\n"); }
void MemoryUtils::ForEachSymbol(void *handle, const std::function<bool(Symbol *)>& functor) { /* do a bogus symbol lookup to force everything into the symbol table cache */ assert(ResolveSymbol(handle, "________________") == nullptr); #ifdef PLATFORM_LINUX struct link_map *dlmap; LibSymbolTable *libtable; SymbolTable *table; dlmap = (struct link_map *)handle; table = NULL; /* See if we already have a symbol table for this library */ for (size_t i = 0; i < m_SymTables.size(); i++) { libtable = m_SymTables[i]; if (libtable->lib_base == dlmap->l_addr) { table = &libtable->table; break; } } /* If we don't have a symbol table for this library, then create one */ if (table == NULL) { libtable = new LibSymbolTable(); libtable->table.Initialize(); libtable->lib_base = dlmap->l_addr; libtable->last_pos = 0; table = &libtable->table; m_SymTables.push_back(libtable); } table->ForEachSymbol(functor); #elif defined PLATFORM_APPLE uintptr_t dlbase; uint32_t image_count; LibSymbolTable *libtable; SymbolTable *table; Symbol *symbol_entry; dlbase = 0; image_count = m_ImageList->infoArrayCount; table = NULL; /* Loop through mach-o images in process. * We can skip index 0 since that is just the executable. */ for (uint32_t i = 1; i < image_count; i++) { const struct dyld_image_info &info = m_ImageList->infoArray[i]; /* "Load" each one until we get a matching handle */ void *h = dlopen(info.imageFilePath, RTLD_NOLOAD); if (h == handle) { dlbase = (uintptr_t)info.imageLoadAddress; dlclose(h); break; } dlclose(h); } if (!dlbase) { /* Uh oh, we couldn't find a matching handle */ return; } /* See if we already have a symbol table for this library */ for (size_t i = 0; i < m_SymTables.size(); i++) { libtable = m_SymTables[i]; if (libtable->lib_base == dlbase) { table = &libtable->table; break; } } /* If we don't have a symbol table for this library, then create one */ if (table == NULL) { libtable = new LibSymbolTable(); libtable->table.Initialize(); libtable->lib_base = dlbase; libtable->last_pos = 0; table = &libtable->table; m_SymTables.push_back(libtable); } table->ForEachSymbol(functor); #endif }