43#ifndef WIN32_LEAN_AND_MEAN
44#define WIN32_LEAN_AND_MEAN
68#define NTAPI __stdcall
73struct dll_notification_data
83#define LDR_DLL_NOTIFICATION_REASON_LOADED 1
86typedef VOID (CALLBACK *LDR_DLL_NOTIFICATION)(ULONG,
87 struct dll_notification_data*,
89typedef NTSTATUS (NTAPI *LDR_REGISTER_FUNCTION)(ULONG,
90 LDR_DLL_NOTIFICATION, PVOID,
130#define PE_MAGIC 0x10b
131#define PEP_MAGIC 0x20b
153 unsigned char zeroes[4];
154 unsigned char off[4];
163 unsigned char section_number[2];
172#define IMAGE_SYM_DTYPE_FUNCTION 2
198 ".debug_str_offsets",
243 error_callback (
data,
"no debug info in PE/COFF executable (make sure to compile with -g)", -1);
279 memcpy (&res, p,
sizeof (res));
290 for (i = 0; i < 8; i++)
304 for (i = 0; i < 8; i++)
306 if (
name[i] != cname[i])
320 if (off >= str_view->
len)
322 return strcmp (
name, (
const char *)str_view->
data + off) == 0;
349 const unsigned char *strtab,
size_t strtab_size)
363 if (off >= strtab_size)
365 isym->
name = (
const char *) strtab + off;
388 size_t syms_size,
const unsigned char *strtab,
395 size_t coff_symstr_len;
396 size_t coff_symbol_count;
397 size_t coff_symbol_size;
403 syms_count = syms_size /
SYM_SZ;
407 coff_symbol_count = 0;
409 for (i = 0; i < syms_count; ++i)
429 coff_symbol_size = (coff_symbol_count + 1) *
sizeof (
struct coff_symbol);
433 if (coff_symbols == NULL)
437 if (coff_symstr_len > 0)
439 coff_symstr = ((
char *)
442 if (coff_symstr == NULL)
453 coff_sym = coff_symbols;
454 coff_str = coff_symstr;
455 for (i = 0; i < syms_count; ++i)
475 memcpy (coff_str, isym.
name, len);
505 coff_sym->
name = NULL;
512 sdata->symbols = coff_symbols;
513 sdata->count = coff_symbol_count;
524 if (!
state->threaded)
567 const uintptr_t *key = (
const uintptr_t *) vkey;
574 else if (addr >= entry[1].
address)
591 if (!
state->threaded)
626 callback (
data, addr, NULL, 0, 0);
637 fileline *fileline_fn,
int *found_sym,
int *found_dwarf,
645 size_t opt_sects_size;
646 unsigned int sects_num;
648 int sects_view_valid;
659 unsigned int syms_num;
665 int debug_view_valid;
674 sects_view_valid = 0;
677 debug_view_valid = 0;
685 const unsigned char *vptr = fhdr_view.
data;
687 if (vptr[0] ==
'M' && vptr[1] ==
'Z')
703 const char *magic = (
const char *) fhdr_view.
data;
704 magic_ok = memcmp (magic,
"PE\0", 4) == 0;
707 memcpy (&fhdr, (
const unsigned char *) fhdr_view.
data + 4,
sizeof fhdr);
711 memcpy (&fhdr, fhdr_view.
data,
sizeof fhdr);
726 opt_sects_off = fhdr_off +
sizeof (fhdr);
738 sects_view_valid = 1;
744 memset (&image_base, 0,
sizeof image_base);
748 image_base.
m = opt_hdr->
u.pe.image_base;
751 image_base.
m = opt_hdr->
u.pep.image_base;
777 syms_size = syms_num *
SYM_SZ;
787 str_off = syms_off + syms_size;
800 memset (sections, 0,
sizeof sections);
803 for (i = 0; i < sects_num; ++i)
806 unsigned int str_off;
809 if (s->
name[0] ==
'/')
812 str_off = atoi (s->
name + 1);
847 syms_view.
data, syms_size,
848 str_view.
data, str_size,
861 sects_view_valid = 0;
877 if (sections[i].size == 0)
879 if (min_offset == 0 || sections[i].offset < min_offset)
880 min_offset = sections[i].
offset;
882 if (end > max_offset)
885 if (min_offset == 0 || max_offset == 0)
894 max_offset - min_offset,
897 debug_view_valid = 1;
906 size_t size = sections[i].
size;
912 + (sections[i].
offset - min_offset));
915 memset (&base_address, 0,
sizeof base_address);
917 base_address.
m = module_handle - image_base.
m;
932 if (sects_view_valid)
938 if (debug_view_valid)
940 if (descriptor != -1)
946struct dll_notification_context
954dll_notification (ULONG reason,
955 struct dll_notification_data *notification_data,
958 char module_name[MAX_PATH];
960 struct dll_notification_context* dll_context =
961 (
struct dll_notification_context*)
context;
963 void *
data = dll_context->data;
968 HMODULE module_handle;
970 if (reason != LDR_DLL_NOTIFICATION_REASON_LOADED)
973 if (!GetModuleHandleExW ((GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
974 | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT),
975 (
wchar_t*) notification_data->dll_base,
979 if (!GetModuleFileNameA ((HMODULE) module_handle, module_name, MAX_PATH - 1))
988 &found_dwarf, (uintptr_t) module_handle);
1006 uintptr_t module_handle = 0;
1007#ifdef HAVE_TLHELP32_H
1009 int module_found_sym;
1013#ifdef HAVE_WINDOWS_H
1014 HMODULE nt_dll_handle;
1016 module_handle = (uintptr_t) GetModuleHandle (NULL);
1020 &coff_fileline_fn, &found_sym, &found_dwarf, module_handle);
1024#ifdef HAVE_TLHELP32_H
1027 snapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0);
1029 while (snapshot == INVALID_HANDLE_VALUE
1030 && GetLastError () == ERROR_BAD_LENGTH);
1032 if (snapshot != INVALID_HANDLE_VALUE)
1034 MODULEENTRY32 entry;
1036 entry.dwSize =
sizeof (MODULEENTRY32);
1038 for (ok = Module32First (snapshot, &entry); ok; ok = Module32Next (snapshot, &entry))
1040 if (strcmp (
filename, entry.szExePath) == 0)
1043 module_handle = (uintptr_t) entry.hModule;
1044 if (module_handle == 0)
1053 &module_fileline_fn, &module_found_sym, &found_dwarf,
1055 if (module_found_sym)
1059 CloseHandle (snapshot);
1063#ifdef HAVE_WINDOWS_H
1064 nt_dll_handle = GetModuleHandleW (
L"ntdll.dll");
1067 LDR_REGISTER_FUNCTION register_func;
1068 const char register_name[] =
"LdrRegisterDllNotification";
1069 register_func = (
void*) GetProcAddress (nt_dll_handle,
1075 struct dll_notification_context *
context
1077 sizeof (
struct dll_notification_context),
1086 register_func (0, &dll_notification,
context, &cookie);
1092 if (!
state->threaded)
1096 else if (
state->syminfo_fn == NULL)
1108 if (!
state->threaded)
1111 *fileline_fn = coff_fileline_fn;
1119 *fileline_fn = coff_fileline_fn;
void * backtrace_alloc(struct backtrace_state *state ATTRIBUTE_UNUSED, size_t size, backtrace_error_callback error_callback, void *data)
void backtrace_free(struct backtrace_state *state ATTRIBUTE_UNUSED, void *p, size_t size ATTRIBUTE_UNUSED, backtrace_error_callback error_callback ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED)
void(* backtrace_syminfo_callback)(void *data, uintptr_t pc, const char *symname, uintptr_t symval, uintptr_t symsize)
void(* backtrace_error_callback)(void *data, const char *msg, int errnum)
int(* backtrace_full_callback)(void *data, uintptr_t pc, const char *filename, int lineno, const char *function)
static void error_callback(void *data, const char *msg, int errnum)
#define L(_str)
Helper for initialising arrays of string literals.
int backtrace_dwarf_add(struct backtrace_state *state, struct libbacktrace_base_address base_address, const struct dwarf_sections *dwarf_sections, int is_bigendian, struct dwarf_data *fileline_altlink, backtrace_error_callback error_callback, void *data, fileline *fileline_fn, struct dwarf_data **fileline_entry)
void backtrace_qsort(void *base, size_t count, size_t size, int(*compar)(const void *, const void *))
void backtrace_release_view(struct backtrace_state *state, struct backtrace_view *view, backtrace_error_callback error_callback, void *data)
#define backtrace_atomic_load_pointer(p)
int(* fileline)(struct backtrace_state *state, uintptr_t pc, backtrace_full_callback callback, backtrace_error_callback error_callback, void *data)
#define libbacktrace_add_base(pc, base)
const unsigned char * data[DEBUG_MAX]
int backtrace_close(int descriptor, backtrace_error_callback error_callback, void *data)
#define backtrace_atomic_store_pointer(p, v)
int backtrace_get_view(struct backtrace_state *state, int descriptor, off_t offset, uint64_t size, backtrace_error_callback error_callback, void *data, struct backtrace_view *view)
int backtrace_open(const char *filename, backtrace_error_callback error_callback, void *data, int *does_not_exist)
#define __sync_bool_compare_and_swap(A, B, C)
static int coff_nodebug(struct backtrace_state *state ATTRIBUTE_UNUSED, uintptr_t pc ATTRIBUTE_UNUSED, backtrace_full_callback callback ATTRIBUTE_UNUSED, backtrace_error_callback error_callback, void *data)
static void coff_nosyms(struct backtrace_state *state ATTRIBUTE_UNUSED, uintptr_t addr ATTRIBUTE_UNUSED, backtrace_syminfo_callback callback ATTRIBUTE_UNUSED, backtrace_error_callback error_callback, void *data)
unsigned char number_of_aux_symbols
unsigned char storage_class
uint16_t number_of_relocations
unsigned char section_number[2]
static void coff_add_syminfo_data(struct backtrace_state *state, struct coff_syminfo_data *sdata)
static size_t coff_short_name_len(const char *name)
uint32_t size_of_uninitialized_data
#define IMAGE_SYM_DTYPE_FUNCTION
uint16_t number_of_line_numbers
static uint16_t coff_read2(const unsigned char *p)
static int coff_symbol_compare(const void *v1, const void *v2)
uint8_t major_linker_version
static int coff_short_name_eq(const char *name, const char *cname)
static int coff_symbol_search(const void *vkey, const void *ventry)
uint8_t minor_linker_version
uint32_t address_of_entry_point
uint32_t pointer_to_relocations
uint32_t number_of_symbols
static int coff_long_name_eq(const char *name, unsigned int off, struct backtrace_view *str_view)
struct coff_symbol * symbols
struct b_coff_name::@7 long_name
uint16_t number_of_sections
static uint32_t coff_read4(const unsigned char *p)
static int coff_expand_symbol(b_coff_internal_symbol *isym, const b_coff_external_symbol *sym, uint16_t sects_num, const unsigned char *strtab, size_t strtab_size)
int backtrace_initialize(struct backtrace_state *state, const char *filename ATTRIBUTE_UNUSED, int descriptor, backtrace_error_callback error_callback, void *data, fileline *fileline_fn)
uint16_t size_of_optional_header
union b_coff_optional_header::@4 u
uint32_t size_of_initialized_data
uint32_t size_of_raw_data
static int coff_initialize_syminfo(struct backtrace_state *state, struct libbacktrace_base_address base_address, int is_64, const b_coff_section_header *sects, size_t sects_num, const b_coff_external_symbol *syms, size_t syms_size, const unsigned char *strtab, size_t strtab_size, backtrace_error_callback error_callback, void *data, struct coff_syminfo_data *sdata)
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, uintptr_t module_handle ATTRIBUTE_UNUSED)
struct coff_syminfo_data * next
uint32_t pointer_to_symbol_table
static const char *const debug_section_names[DEBUG_MAX]
static int coff_is_function_symbol(const b_coff_internal_symbol *isym)
static void coff_syminfo(struct backtrace_state *state, uintptr_t addr, backtrace_syminfo_callback callback, backtrace_error_callback error_callback ATTRIBUTE_UNUSED, void *data)
uint32_t pointer_to_raw_data
uint32_t pointer_to_line_numbers
fr_aka_sim_id_type_t type
Functions to help with cleanup.