Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}