static struct a2l_data *addr2line_init(const char *path) { bfd *abfd; struct a2l_data *a2l = NULL; abfd = bfd_openr(path, NULL); if (abfd == NULL) return NULL; if (!bfd_check_format(abfd, bfd_object)) goto out; a2l = zalloc(sizeof(*a2l)); if (a2l == NULL) goto out; a2l->abfd = abfd; a2l->input = strdup(path); if (a2l->input == NULL) goto out; if (slurp_symtab(abfd, a2l)) goto out; return a2l; out: if (a2l) { zfree((char **)&a2l->input); free(a2l); } bfd_close(abfd); return NULL; }
static bool fill_bfd_cache(const char *filename, bfd_cache *p) { bfd *abfd = bfd_openr(filename, NULL); // hard to avoid heap here! if (!abfd) return true; p->abfd = abfd; p->syms = NULL; char **match; if (bfd_check_format(abfd, bfd_archive) || !bfd_check_format_matches(abfd, bfd_object, &match) || !slurp_symtab(&p->syms, abfd)) { bfd_close(abfd); return true; } return false; }
static bool fill_bfd_cache(const char *filename, bfd_cache *p) { bfd *abfd = bfd_openr(filename, nullptr); // hard to avoid heap here! if (!abfd) return true; // Some systems don't have the BFD_DECOMPRESS flag #ifdef BFD_DECOMPRESS abfd->flags |= BFD_DECOMPRESS; #endif p->abfd = abfd; p->syms = nullptr; char **match; if (bfd_check_format(abfd, bfd_archive) || !bfd_check_format_matches(abfd, bfd_object, &match) || !slurp_symtab(&p->syms, abfd)) { bfd_close(abfd); return true; } return false; }
static bfd_cache_ptr get_bfd_cache(const char *filename) { bfdMap::const_iterator iter = s_bfds.find(filename); if (iter != s_bfds.end()) { return iter->second; } bfd_cache_ptr p(new bfd_cache()); bfd *abfd = bfd_openr(filename, NULL); if (abfd) { p->abfd = abfd; p->syms = NULL; char **match; if (bfd_check_format(abfd, bfd_archive) || !bfd_check_format_matches(abfd, bfd_object, &match) || !slurp_symtab(&p->syms, abfd)) { bfd_close(abfd); p.reset(); } } else { p.reset(); } s_bfds[filename] = p; return p; }
static BOOL StackBackTrace(HANDLE hProcess, HANDLE hThread, PCONTEXT pContext) { STACKFRAME StackFrame; HMODULE hModule = NULL; TCHAR szModule[MAX_PATH]; #ifdef HAVE_BFD bfd *abfd = NULL; asymbol **syms = NULL; // The symbol table. long symcount = 0; // Number of symbols in `syms'. #endif /* HAVE_BFD */ assert(!bSymInitialized); j_SymSetOptions(/* SYMOPT_UNDNAME | */ SYMOPT_LOAD_LINES); if(j_SymInitialize(hProcess, NULL, TRUE)) bSymInitialized = TRUE; memset( &StackFrame, 0, sizeof(StackFrame) ); // Initialize the STACKFRAME structure for the first call. This is only // necessary for Intel CPUs, and isn't mentioned in the documentation. StackFrame.AddrPC.Offset = pContext->Eip; StackFrame.AddrPC.Mode = AddrModeFlat; StackFrame.AddrStack.Offset = pContext->Esp; StackFrame.AddrStack.Mode = AddrModeFlat; StackFrame.AddrFrame.Offset = pContext->Ebp; StackFrame.AddrFrame.Mode = AddrModeFlat; rprintf( _T("Call stack:\r\n") ); if(0) rprintf( _T("AddrPC AddrReturn AddrFrame AddrStack\r\n") ); while ( 1 ) { BOOL bSuccess = FALSE; #ifdef HAVE_BFD const HMODULE hPrevModule = hModule; #endif /* HAVE_BFD */ TCHAR szSymName[512] = _T(""); TCHAR szFileName[MAX_PATH] = _T(""); DWORD LineNumber = 0; if(bSymInitialized) { if(!j_StackWalk( IMAGE_FILE_MACHINE_I386, hProcess, hThread, &StackFrame, pContext, NULL, j_SymFunctionTableAccess, j_SymGetModuleBase, NULL ) ) break; } else { if(!IntelStackWalk( IMAGE_FILE_MACHINE_I386, hProcess, hThread, &StackFrame, pContext, NULL, NULL, NULL, NULL ) ) break; } // Basic sanity check to make sure the frame is OK. Bail if not. if ( 0 == StackFrame.AddrFrame.Offset ) break; if(0) { rprintf( _T("%08lX %08lX %08lX %08lX\r\n"), StackFrame.AddrPC.Offset, StackFrame.AddrReturn.Offset, StackFrame.AddrFrame.Offset, StackFrame.AddrStack.Offset ); rprintf( _T("%08lX %08lX %08lX %08lX\r\n"), StackFrame.Params[0], StackFrame.Params[1], StackFrame.Params[2], StackFrame.Params[3] ); } rprintf( _T("%08lX"), StackFrame.AddrPC.Offset); if((hModule = (HMODULE) GetModuleBase(StackFrame.AddrPC.Offset)) && GetModuleFileName(hModule, szModule, sizeof(szModule))) { #ifndef HAVE_BFD rprintf( _T(" %s:ModulBase %08lX"), szModule, hModule); #else /* HAVE_BFD */ rprintf( _T(" %s:%08lX"), szModule, StackFrame.AddrPC.Offset); if(hModule != hPrevModule) { if(syms) { GlobalFree(syms); syms = NULL; symcount = 0; } if(abfd) bfd_close(abfd); if((abfd = bfd_openr (szModule, NULL))) if(bfd_check_format(abfd, bfd_object)) { bfd_vma adjust_section_vma = 0; /* If we are adjusting section VMA's, change them all now. Changing the BFD information is a hack. However, we must do it, or bfd_find_nearest_line will not do the right thing. */ if ((adjust_section_vma = (bfd_vma) hModule - pe_data(abfd)->pe_opthdr.ImageBase)) { asection *s; for (s = abfd->sections; s != NULL; s = s->next) { s->vma += adjust_section_vma; s->lma += adjust_section_vma; } } if(bfd_get_file_flags(abfd) & HAS_SYMS) /* Read in the symbol table. */ slurp_symtab(abfd, &syms, &symcount); } } if(!bSuccess && abfd && syms && symcount) if((bSuccess = BfdGetSymFromAddr(abfd, syms, symcount, StackFrame.AddrPC.Offset, szSymName, 512))) { /* framepointer = StackFrame.AddrFrame.Offset; hprocess = hProcess; */ BfdDemangleSymName(szSymName, szSymName, 512); rprintf( _T(" %s"), szSymName); if(BfdGetLineFromAddr(abfd, syms, symcount, StackFrame.AddrPC.Offset, szFileName, MAX_PATH, &LineNumber)) rprintf( _T(" %s:%ld"), szFileName, LineNumber); } #endif /* HAVE_BFD */ if(!bSuccess && bSymInitialized) if((bSuccess = ImagehlpGetSymFromAddr(hProcess, StackFrame.AddrPC.Offset, szSymName, 512))) { rprintf( _T(" %s"), szSymName); ImagehlpDemangleSymName(szSymName, szSymName, 512); if(ImagehlpGetLineFromAddr(hProcess, StackFrame.AddrPC.Offset, szFileName, MAX_PATH, &LineNumber)) rprintf( _T(" %s:%ld"), szFileName, LineNumber); } if(!bSuccess) if((bSuccess = PEGetSymFromAddr(hProcess, StackFrame.AddrPC.Offset, szSymName, 512))) rprintf( _T(" %s"), szSymName); } rprintf(_T("\r\n")); } #ifdef HAVE_BFD if(syms) { GlobalFree(syms); syms = NULL; symcount = 0; } if(abfd) bfd_close(abfd); #endif /* HAVE_BFD */ if(bSymInitialized) { if(!j_SymCleanup(hProcess)) assert(0); bSymInitialized = FALSE; } return TRUE; }