// Entry point where control comes on an unhandled exception static LONG WINAPI TopLevelExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo) { static BOOL bBeenHere = FALSE; if(!bBeenHere) { UINT fuOldErrorMode; bBeenHere = TRUE; fuOldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); #ifdef HAVE_BFD bfd_set_error_handler((bfd_error_handler_type) rprintf); #endif /* HAVE_BFD */ GenerateExceptionReport(pExceptionInfo); SetErrorMode(fuOldErrorMode); } if(prevExceptionFilter) return prevExceptionFilter(pExceptionInfo); else return EXCEPTION_CONTINUE_SEARCH; }
int main(int argc, char **argv) { if (argc <= 1) { fprintf(stderr, "Usage: %s <filename> <var1> <var2>\n\n", argv[0]); fprintf(stderr, "Where var1/var2 are variables in the program\n"); fprintf(stderr, "E.g.: %s ./%s main abfd\n", argv[0], argv[0]); exit(ERROR); } bfd_init(); bfd_set_error_handler((bfd_error_handler_type)bfderror); abfd = bfd_openr(argv[1], NULL); if (abfd == NULL) { bfderror("[bfd_openr] error with opening %s", argv[1]); exit(ERROR); } setup(), showStats(); printf("\nHit enter to continue..."), (void)getchar(); dumpsects(bfd_get_section_by_name(abfd, ".text")); dumpsects(bfd_get_section_by_name(abfd, ".plt")); dumpsects(bfd_get_section_by_name(abfd, ".data")); dumpsects(bfd_get_section_by_name(abfd, ".bss")); getSyms(argv[2], argv[3]); bfd_close(abfd); return 0; }
// Entry point where control comes on an unhandled exception static LONG WINAPI TopLevelExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo) { static BOOL bBeenHere = FALSE; if(!bBeenHere) { UINT fuOldErrorMode; bBeenHere = TRUE; fuOldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); hReportFile = CreateFile( szLogFileName, GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_FLAG_WRITE_THROUGH, 0 ); if (hReportFile == INVALID_HANDLE_VALUE) { // Retrieve the system error message for the last-error code LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = GetLastError(); TCHAR szBuffer[4196]; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); wsprintf(szBuffer, _T("Exception handler failed with error %d: %s\n"), dw, lpMsgBuf); MessageBox(MB_ICONEXCLAMATION, szBuffer, _T("Error"), MB_OK); LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); debug(LOG_ERROR, "Exception handler failed to create file!"); } #ifdef HAVE_BFD bfd_set_error_handler((bfd_error_handler_type) rprintf); #endif /* HAVE_BFD */ if (hReportFile) { TCHAR szBuffer[4196]; int err; SetFilePointer(hReportFile, 0, 0, FILE_END); // FIXME: We don't return from the below function call GenerateExceptionReport(pExceptionInfo); CloseHandle(hReportFile); wsprintf(szBuffer, _T("Warzone has crashed.\r\nSee %s for more details\r\n"), szLogFileName); err = MessageBox(MB_ICONERROR, szBuffer, _T("Warzone Crashed!"), MB_OK | MB_ICONERROR); if (err == 0) { LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = GetLastError(); TCHAR szBuffer[4196]; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); wsprintf(szBuffer, _T("Exception handler failed with error %d: %s\n"), dw, lpMsgBuf); MessageBox(MB_ICONEXCLAMATION, szBuffer, _T("Error"), MB_OK); LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); debug(LOG_ERROR, "Exception handler failed to create file!"); } hReportFile = 0; } SetErrorMode(fuOldErrorMode); } if(prevExceptionFilter) return prevExceptionFilter(pExceptionInfo); else return EXCEPTION_CONTINUE_SEARCH; }
int main (int argc, char **argv) { char *emulation; long start_time = get_run_time (); #ifdef HAVE_SBRK char *start_sbrk = (char *) sbrk (0); #endif #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) setlocale (LC_MESSAGES, ""); #endif #if defined (HAVE_SETLOCALE) setlocale (LC_CTYPE, ""); #endif bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); program_name = argv[0]; xmalloc_set_program_name (program_name); START_PROGRESS (program_name, 0); expandargv (&argc, &argv); bfd_init (); bfd_set_error_program_name (program_name); /* We want to notice and fail on those nasty BFD assertions which are likely to signal incorrect output being generated but otherwise may leave no trace. */ default_bfd_assert_handler = bfd_set_assert_handler (ld_bfd_assert_handler); /* Also hook the bfd error/warning handler for --fatal-warnings. */ default_bfd_error_handler = bfd_set_error_handler (ld_bfd_error_handler); xatexit (ld_cleanup); /* Set up the sysroot directory. */ ld_sysroot = get_sysroot (argc, argv); if (*ld_sysroot) ld_canon_sysroot = lrealpath (ld_sysroot); if (ld_canon_sysroot) ld_canon_sysroot_len = strlen (ld_canon_sysroot); else ld_canon_sysroot_len = -1; /* Set the default BFD target based on the configured target. Doing this permits the linker to be configured for a particular target, and linked against a shared BFD library which was configured for a different target. The macro TARGET is defined by Makefile. */ if (!bfd_set_default_target (TARGET)) { einfo (_("%X%P: can't set BFD default target to `%s': %E\n"), TARGET); xexit (1); } #if YYDEBUG { extern int yydebug; yydebug = 1; } #endif config.build_constructors = TRUE; config.rpath_separator = ':'; config.split_by_reloc = (unsigned) -1; config.split_by_file = (bfd_size_type) -1; config.make_executable = TRUE; config.magic_demand_paged = TRUE; config.text_read_only = TRUE; link_info.disable_target_specific_optimizations = -1; command_line.warn_mismatch = TRUE; command_line.warn_search_mismatch = TRUE; command_line.check_section_addresses = -1; /* We initialize DEMANGLING based on the environment variable COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the output of the linker, unless COLLECT_NO_DEMANGLE is set in the environment. Acting the same way here lets us provide the same interface by default. */ demangling = getenv ("COLLECT_NO_DEMANGLE") == NULL; link_info.allow_undefined_version = TRUE; link_info.keep_memory = TRUE; link_info.combreloc = TRUE; link_info.strip_discarded = TRUE; link_info.emit_hash = TRUE; link_info.callbacks = &link_callbacks; link_info.input_bfds_tail = &link_info.input_bfds; /* SVR4 linkers seem to set DT_INIT and DT_FINI based on magic _init and _fini symbols. We are compatible. */ link_info.init_function = "_init"; link_info.fini_function = "_fini"; link_info.relax_pass = 1; link_info.extern_protected_data = -1; link_info.dynamic_undefined_weak = -1; link_info.pei386_auto_import = -1; link_info.spare_dynamic_tags = 5; link_info.path_separator = ':'; #ifdef DEFAULT_FLAG_COMPRESS_DEBUG link_info.compress_debug = COMPRESS_DEBUG_GABI_ZLIB; #endif ldfile_add_arch (""); emulation = get_emulation (argc, argv); ldemul_choose_mode (emulation); default_target = ldemul_choose_target (argc, argv); config.maxpagesize = bfd_emul_get_maxpagesize (default_target); config.commonpagesize = bfd_emul_get_commonpagesize (default_target); lang_init (); ldexp_init (); ldemul_before_parse (); lang_has_input_file = FALSE; parse_args (argc, argv); if (config.hash_table_size != 0) bfd_hash_set_default_size (config.hash_table_size); #ifdef ENABLE_PLUGINS /* Now all the plugin arguments have been gathered, we can load them. */ plugin_load_plugins (); #endif /* ENABLE_PLUGINS */ ldemul_set_symbols (); /* If we have not already opened and parsed a linker script, try the default script from command line first. */ if (saved_script_handle == NULL && command_line.default_script != NULL) { ldfile_open_command_file (command_line.default_script); parser_input = input_script; yyparse (); } /* If we have not already opened and parsed a linker script read the emulation's appropriate default script. */ if (saved_script_handle == NULL) { int isfile; char *s = ldemul_get_script (&isfile); if (isfile) ldfile_open_default_command_file (s); else { lex_string = s; lex_redirect (s, _("built in linker script"), 1); } parser_input = input_script; yyparse (); lex_string = NULL; } if (verbose) { if (saved_script_handle) info_msg (_("using external linker script:")); else info_msg (_("using internal linker script:")); info_msg ("\n==================================================\n"); if (saved_script_handle) { static const int ld_bufsz = 8193; size_t n; char *buf = (char *) xmalloc (ld_bufsz); rewind (saved_script_handle); while ((n = fread (buf, 1, ld_bufsz - 1, saved_script_handle)) > 0) { buf[n] = 0; info_msg ("%s", buf); } rewind (saved_script_handle); free (buf); } else { int isfile; info_msg (ldemul_get_script (&isfile)); } info_msg ("\n==================================================\n"); } if (command_line.print_output_format) info_msg ("%s\n", lang_get_output_target ()); lang_final (); /* If the only command line argument has been -v or --version or --verbose then ignore any input files provided by linker scripts and exit now. We do not want to create an output file when the linker is just invoked to provide version information. */ if (argc == 2 && version_printed) xexit (0); if (!lang_has_input_file) { if (version_printed || command_line.print_output_format) xexit (0); einfo (_("%P%F: no input files\n")); } if (trace_files) info_msg (_("%P: mode %s\n"), emulation); ldemul_after_parse (); if (config.map_filename) { if (strcmp (config.map_filename, "-") == 0) { config.map_file = stdout; } else { config.map_file = fopen (config.map_filename, FOPEN_WT); if (config.map_file == (FILE *) NULL) { bfd_set_error (bfd_error_system_call); einfo (_("%P%F: cannot open map file %s: %E\n"), config.map_filename); } } } lang_process (); /* Print error messages for any missing symbols, for any warning symbols, and possibly multiple definitions. */ if (bfd_link_relocatable (&link_info)) link_info.output_bfd->flags &= ~EXEC_P; else link_info.output_bfd->flags |= EXEC_P; if ((link_info.compress_debug & COMPRESS_DEBUG)) { link_info.output_bfd->flags |= BFD_COMPRESS; if (link_info.compress_debug == COMPRESS_DEBUG_GABI_ZLIB) link_info.output_bfd->flags |= BFD_COMPRESS_GABI; } ldwrite (); if (config.map_file != NULL) lang_map (); if (command_line.cref) output_cref (config.map_file != NULL ? config.map_file : stdout); if (nocrossref_list != NULL) check_nocrossrefs (); if (command_line.print_memory_usage) lang_print_memory_usage (); #if 0 { struct bfd_link_hash_entry *h; h = bfd_link_hash_lookup (link_info.hash, "__image_base__", 0,0,1); fprintf (stderr, "lookup = %p val %lx\n", h, h ? h->u.def.value : 1); } #endif ldexp_finish (); lang_finish (); /* Even if we're producing relocatable output, some non-fatal errors should be reported in the exit status. (What non-fatal errors, if any, do we want to ignore for relocatable output?) */ if (!config.make_executable && !force_make_executable) { if (trace_files) einfo (_("%P: link errors found, deleting executable `%s'\n"), output_filename); /* The file will be removed by ld_cleanup. */ xexit (1); } else { if (!bfd_close (link_info.output_bfd)) einfo (_("%F%B: final close failed: %E\n"), link_info.output_bfd); /* If the --force-exe-suffix is enabled, and we're making an executable file and it doesn't end in .exe, copy it to one which does. */ if (!bfd_link_relocatable (&link_info) && command_line.force_exe_suffix) { int len = strlen (output_filename); if (len < 4 || (strcasecmp (output_filename + len - 4, ".exe") != 0 && strcasecmp (output_filename + len - 4, ".dll") != 0)) { FILE *src; FILE *dst; const int bsize = 4096; char *buf = (char *) xmalloc (bsize); int l; char *dst_name = (char *) xmalloc (len + 5); strcpy (dst_name, output_filename); strcat (dst_name, ".exe"); src = fopen (output_filename, FOPEN_RB); dst = fopen (dst_name, FOPEN_WB); if (!src) einfo (_("%P%F: unable to open for source of copy `%s'\n"), output_filename); if (!dst) einfo (_("%P%F: unable to open for destination of copy `%s'\n"), dst_name); while ((l = fread (buf, 1, bsize, src)) > 0) { int done = fwrite (buf, 1, l, dst); if (done != l) einfo (_("%P: Error writing file `%s'\n"), dst_name); } fclose (src); if (fclose (dst) == EOF) einfo (_("%P: Error closing file `%s'\n"), dst_name); free (dst_name); free (buf); } } } END_PROGRESS (program_name); if (config.stats) { #ifdef HAVE_SBRK char *lim = (char *) sbrk (0); #endif long run_time = get_run_time () - start_time; fflush (stdout); fprintf (stderr, _("%s: total time in link: %ld.%06ld\n"), program_name, run_time / 1000000, run_time % 1000000); #ifdef HAVE_SBRK fprintf (stderr, _("%s: data size %ld\n"), program_name, (long) (lim - start_sbrk)); #endif fflush (stderr); } /* Prevent ld_cleanup from doing anything, after a successful link. */ output_filename = NULL; xexit (0); return 0; }