diff options
author | Ian Lance Taylor <iant@golang.org> | 2024-04-28 11:14:17 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2024-04-28 11:14:17 -0700 |
commit | 942a9cf2a958113d2ab46f5b015c36e569abedcf (patch) | |
tree | f759dc6a62c1e8d0e0e6a48bf423aa299ef42d00 | |
parent | 507f3ce34c55e78b23eeaf57bc4d927a1f25f8fb (diff) | |
download | gcc-942a9cf2a958113d2ab46f5b015c36e569abedcf.zip gcc-942a9cf2a958113d2ab46f5b015c36e569abedcf.tar.gz gcc-942a9cf2a958113d2ab46f5b015c36e569abedcf.tar.bz2 |
libbacktrace: load Windows modules
Patch from Björn Schäpers <bjoern@hazardy.de>.
* configure.ac: Checked for tlhelp32.h
* pecoff.c: Include <tlhelp32.h> if available.
(backtrace_initialize): Use tlhelp32 api for a snapshot to
detect loaded modules.
(coff_add): New argument for the module handle of the file,
to get the base address.
* configure, config.h.in: Regenerate.
-rw-r--r-- | libbacktrace/config.h.in | 3 | ||||
-rwxr-xr-x | libbacktrace/configure | 15 | ||||
-rw-r--r-- | libbacktrace/configure.ac | 4 | ||||
-rw-r--r-- | libbacktrace/pecoff.c | 73 |
4 files changed, 87 insertions, 8 deletions
diff --git a/libbacktrace/config.h.in b/libbacktrace/config.h.in index ee26163..9b8ab88 100644 --- a/libbacktrace/config.h.in +++ b/libbacktrace/config.h.in @@ -101,6 +101,9 @@ /* Define to 1 if you have the <sys/types.h> header file. */ #undef HAVE_SYS_TYPES_H +/* Define to 1 if you have the <tlhelp32.h> header file. */ +#undef HAVE_TLHELP32_H + /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H diff --git a/libbacktrace/configure b/libbacktrace/configure index d6d6606..ab94a85 100755 --- a/libbacktrace/configure +++ b/libbacktrace/configure @@ -13523,6 +13523,21 @@ fi done +for ac_header in tlhelp32.h +do : + ac_fn_c_check_header_compile "$LINENO" "tlhelp32.h" "ac_cv_header_tlhelp32_h" "#ifdef HAVE_WINDOWS_H +# include <windows.h> +#endif +" +if test "x$ac_cv_header_tlhelp32_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_TLHELP32_H 1 +_ACEOF + +fi + +done + # Check for the fcntl function. if test -n "${with_target_subdir}"; then diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac index 3e0075a..59e9c41 100644 --- a/libbacktrace/configure.ac +++ b/libbacktrace/configure.ac @@ -380,6 +380,10 @@ if test "$have_loadquery" = "yes"; then fi AC_CHECK_HEADERS(windows.h) +AC_CHECK_HEADERS(tlhelp32.h, [], [], +[#ifdef HAVE_WINDOWS_H +# include <windows.h> +#endif]) # Check for the fcntl function. if test -n "${with_target_subdir}"; then diff --git a/libbacktrace/pecoff.c b/libbacktrace/pecoff.c index 9e437d8..4f26784 100644 --- a/libbacktrace/pecoff.c +++ b/libbacktrace/pecoff.c @@ -49,6 +49,18 @@ POSSIBILITY OF SUCH DAMAGE. */ #endif #include <windows.h> + +#ifdef HAVE_TLHELP32_H +#include <tlhelp32.h> + +#ifdef UNICODE +/* If UNICODE is defined, all the symbols are replaced by a macro to use the + wide variant. But we need the ansi variant, so undef the macros. */ +#undef MODULEENTRY32 +#undef Module32First +#undef Module32Next +#endif +#endif #endif /* Coff file header. */ @@ -592,7 +604,8 @@ coff_syminfo (struct backtrace_state *state, uintptr_t addr, static int coff_add (struct backtrace_state *state, int descriptor, backtrace_error_callback error_callback, void *data, - fileline *fileline_fn, int *found_sym, int *found_dwarf) + fileline *fileline_fn, int *found_sym, int *found_dwarf, + uintptr_t module_handle ATTRIBUTE_UNUSED) { struct backtrace_view fhdr_view; off_t fhdr_off; @@ -870,12 +883,7 @@ coff_add (struct backtrace_state *state, int descriptor, } #ifdef HAVE_WINDOWS_H - { - uintptr_t module_handle; - - module_handle = (uintptr_t) GetModuleHandle (NULL); - base_address = module_handle - image_base; - } + base_address = module_handle - image_base; #endif if (!backtrace_dwarf_add (state, base_address, &dwarf_sections, @@ -917,12 +925,61 @@ backtrace_initialize (struct backtrace_state *state, int found_sym; int found_dwarf; fileline coff_fileline_fn; + uintptr_t module_handle = 0; +#ifdef HAVE_TLHELP32_H + fileline module_fileline_fn; + int module_found_sym; + HANDLE snapshot; +#endif + +#ifdef HAVE_WINDOWS_H + module_handle = (uintptr_t) GetModuleHandle (NULL); +#endif ret = coff_add (state, descriptor, error_callback, data, - &coff_fileline_fn, &found_sym, &found_dwarf); + &coff_fileline_fn, &found_sym, &found_dwarf, module_handle); if (!ret) return 0; +#ifdef HAVE_TLHELP32_H + do + { + snapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0); + } + while (snapshot == INVALID_HANDLE_VALUE + && GetLastError () == ERROR_BAD_LENGTH); + + if (snapshot != INVALID_HANDLE_VALUE) + { + MODULEENTRY32 entry; + BOOL ok; + entry.dwSize = sizeof (MODULEENTRY32); + + for (ok = Module32First (snapshot, &entry); ok; ok = Module32Next (snapshot, &entry)) + { + if (strcmp (filename, entry.szExePath) == 0) + continue; + + module_handle = (uintptr_t) entry.hModule; + if (module_handle == 0) + continue; + + descriptor = backtrace_open (entry.szExePath, error_callback, data, + NULL); + if (descriptor < 0) + continue; + + coff_add (state, descriptor, error_callback, data, + &module_fileline_fn, &module_found_sym, &found_dwarf, + module_handle); + if (module_found_sym) + found_sym = 1; + } + + CloseHandle (snapshot); + } +#endif + if (!state->threaded) { if (found_sym) |