You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-05 12:10:55 +00:00
Merge pull request #100274 from akien-mga/libbacktrace-1db8564
libbacktrace: Update to upstream commit 1db85642e
This commit is contained in:
6
thirdparty/README.md
vendored
6
thirdparty/README.md
vendored
@@ -460,12 +460,14 @@ Files extracted from upstream source:
|
|||||||
## libbacktrace
|
## libbacktrace
|
||||||
|
|
||||||
- Upstream: https://github.com/ianlancetaylor/libbacktrace
|
- Upstream: https://github.com/ianlancetaylor/libbacktrace
|
||||||
- Version: git (4d2dd0b172f2c9192f83ba93425f868f2a13c553, 2022)
|
- Version: git (1db85642e3fca189cf4e076f840a45d6934b2456, 2024)
|
||||||
- License: BSD-3-Clause
|
- License: BSD-3-Clause
|
||||||
|
|
||||||
Files extracted from upstream source:
|
Files extracted from upstream source:
|
||||||
|
|
||||||
- `*.{c,h}` files for Windows platform
|
- `*.{c,h}` files for Windows platform, i.e. remove the following:
|
||||||
|
* `allocfail.c`, `instrumented_alloc.c`, `*test*.{c,h}`
|
||||||
|
* `elf.c`, `macho.c`, `mmap.c`, `mmapio.c`, `nounwind.c`, `unknown.c`, `xcoff.c`
|
||||||
- `LICENSE`
|
- `LICENSE`
|
||||||
|
|
||||||
Important: Some files have Godot-made changes to load big debug symbol files.
|
Important: Some files have Godot-made changes to load big debug symbol files.
|
||||||
|
|||||||
2
thirdparty/libbacktrace/alloc.c
vendored
2
thirdparty/libbacktrace/alloc.c
vendored
@@ -1,5 +1,5 @@
|
|||||||
/* alloc.c -- Memory allocation without mmap.
|
/* alloc.c -- Memory allocation without mmap.
|
||||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
Copyright (C) 2012-2024 Free Software Foundation, Inc.
|
||||||
Written by Ian Lance Taylor, Google.
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
|||||||
2
thirdparty/libbacktrace/atomic.c
vendored
2
thirdparty/libbacktrace/atomic.c
vendored
@@ -1,5 +1,5 @@
|
|||||||
/* atomic.c -- Support for atomic functions if not present.
|
/* atomic.c -- Support for atomic functions if not present.
|
||||||
Copyright (C) 2013-2021 Free Software Foundation, Inc.
|
Copyright (C) 2013-2024 Free Software Foundation, Inc.
|
||||||
Written by Ian Lance Taylor, Google.
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* backtrace-supported.h.in -- Whether stack backtrace is supported.
|
/* backtrace-supported.h.in -- Whether stack backtrace is supported.
|
||||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
Copyright (C) 2012-2024 Free Software Foundation, Inc.
|
||||||
Written by Ian Lance Taylor, Google.
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
|||||||
2
thirdparty/libbacktrace/backtrace.c
vendored
2
thirdparty/libbacktrace/backtrace.c
vendored
@@ -1,5 +1,5 @@
|
|||||||
/* backtrace.c -- Entry point for stack backtrace library.
|
/* backtrace.c -- Entry point for stack backtrace library.
|
||||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
Copyright (C) 2012-2024 Free Software Foundation, Inc.
|
||||||
Written by Ian Lance Taylor, Google.
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
|||||||
2
thirdparty/libbacktrace/backtrace.h
vendored
2
thirdparty/libbacktrace/backtrace.h
vendored
@@ -1,5 +1,5 @@
|
|||||||
/* backtrace.h -- Public header file for stack backtrace library.
|
/* backtrace.h -- Public header file for stack backtrace library.
|
||||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
Copyright (C) 2012-2024 Free Software Foundation, Inc.
|
||||||
Written by Ian Lance Taylor, Google.
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
|||||||
18
thirdparty/libbacktrace/config.h
vendored
18
thirdparty/libbacktrace/config.h
vendored
@@ -21,6 +21,10 @@
|
|||||||
don't. */
|
don't. */
|
||||||
#define HAVE_DECL_STRNLEN 1
|
#define HAVE_DECL_STRNLEN 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the declaration of `_pgmptr', and to 0 if you
|
||||||
|
don't. */
|
||||||
|
#define HAVE_DECL__PGMPTR 1
|
||||||
|
|
||||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||||
/* #undef HAVE_DLFCN_H */
|
/* #undef HAVE_DLFCN_H */
|
||||||
|
|
||||||
@@ -48,7 +52,7 @@
|
|||||||
/* #undef HAVE_KERN_PROC_ARGS */
|
/* #undef HAVE_KERN_PROC_ARGS */
|
||||||
|
|
||||||
/* Define if -llzma is available. */
|
/* Define if -llzma is available. */
|
||||||
#define HAVE_LIBLZMA 1
|
/* #undef HAVE_LIBLZMA */
|
||||||
|
|
||||||
/* Define to 1 if you have the <link.h> header file. */
|
/* Define to 1 if you have the <link.h> header file. */
|
||||||
/* #undef HAVE_LINK_H */
|
/* #undef HAVE_LINK_H */
|
||||||
@@ -86,6 +90,9 @@
|
|||||||
/* Define to 1 if you have the <sys/ldr.h> header file. */
|
/* Define to 1 if you have the <sys/ldr.h> header file. */
|
||||||
/* #undef HAVE_SYS_LDR_H */
|
/* #undef HAVE_SYS_LDR_H */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/link.h> header file. */
|
||||||
|
/* #undef HAVE_SYS_LINK_H */
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||||
/* #undef HAVE_SYS_MMAN_H */
|
/* #undef HAVE_SYS_MMAN_H */
|
||||||
|
|
||||||
@@ -95,12 +102,21 @@
|
|||||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||||
#define HAVE_SYS_TYPES_H 1
|
#define HAVE_SYS_TYPES_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <tlhelp32.h> header file. */
|
||||||
|
#define HAVE_TLHELP32_H 1
|
||||||
|
|
||||||
/* Define to 1 if you have the <unistd.h> header file. */
|
/* Define to 1 if you have the <unistd.h> header file. */
|
||||||
#define HAVE_UNISTD_H 1
|
#define HAVE_UNISTD_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <windows.h> header file. */
|
||||||
|
#define HAVE_WINDOWS_H 1
|
||||||
|
|
||||||
/* Define if -lz is available. */
|
/* Define if -lz is available. */
|
||||||
#define HAVE_ZLIB 1
|
#define HAVE_ZLIB 1
|
||||||
|
|
||||||
|
/* Define if -lzstd is available. */
|
||||||
|
/* #undef HAVE_ZSTD */
|
||||||
|
|
||||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||||
*/
|
*/
|
||||||
#define LT_OBJDIR ".libs/"
|
#define LT_OBJDIR ".libs/"
|
||||||
|
|||||||
363
thirdparty/libbacktrace/dwarf.c
vendored
363
thirdparty/libbacktrace/dwarf.c
vendored
@@ -1,5 +1,5 @@
|
|||||||
/* dwarf.c -- Get file/line information from DWARF for backtraces.
|
/* dwarf.c -- Get file/line information from DWARF for backtraces.
|
||||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
Copyright (C) 2012-2024 Free Software Foundation, Inc.
|
||||||
Written by Ian Lance Taylor, Google.
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -470,7 +470,7 @@ enum attr_val_encoding
|
|||||||
/* An address. */
|
/* An address. */
|
||||||
ATTR_VAL_ADDRESS,
|
ATTR_VAL_ADDRESS,
|
||||||
/* An index into the .debug_addr section, whose value is relative to
|
/* An index into the .debug_addr section, whose value is relative to
|
||||||
* the DW_AT_addr_base attribute of the compilation unit. */
|
the DW_AT_addr_base attribute of the compilation unit. */
|
||||||
ATTR_VAL_ADDRESS_INDEX,
|
ATTR_VAL_ADDRESS_INDEX,
|
||||||
/* A unsigned integer. */
|
/* A unsigned integer. */
|
||||||
ATTR_VAL_UINT,
|
ATTR_VAL_UINT,
|
||||||
@@ -608,8 +608,8 @@ struct function
|
|||||||
struct function_addrs
|
struct function_addrs
|
||||||
{
|
{
|
||||||
/* Range is LOW <= PC < HIGH. */
|
/* Range is LOW <= PC < HIGH. */
|
||||||
uint64_t low;
|
uintptr_t low;
|
||||||
uint64_t high;
|
uintptr_t high;
|
||||||
/* Function for this address range. */
|
/* Function for this address range. */
|
||||||
struct function *function;
|
struct function *function;
|
||||||
};
|
};
|
||||||
@@ -690,8 +690,8 @@ struct unit
|
|||||||
struct unit_addrs
|
struct unit_addrs
|
||||||
{
|
{
|
||||||
/* Range is LOW <= PC < HIGH. */
|
/* Range is LOW <= PC < HIGH. */
|
||||||
uint64_t low;
|
uintptr_t low;
|
||||||
uint64_t high;
|
uintptr_t high;
|
||||||
/* Compilation unit for this address range. */
|
/* Compilation unit for this address range. */
|
||||||
struct unit *u;
|
struct unit *u;
|
||||||
};
|
};
|
||||||
@@ -722,8 +722,8 @@ struct dwarf_data
|
|||||||
struct dwarf_data *next;
|
struct dwarf_data *next;
|
||||||
/* The data for .gnu_debugaltlink. */
|
/* The data for .gnu_debugaltlink. */
|
||||||
struct dwarf_data *altlink;
|
struct dwarf_data *altlink;
|
||||||
/* The base address for this file. */
|
/* The base address mapping for this file. */
|
||||||
uintptr_t base_address;
|
struct libbacktrace_base_address base_address;
|
||||||
/* A sorted list of address ranges. */
|
/* A sorted list of address ranges. */
|
||||||
struct unit_addrs *addrs;
|
struct unit_addrs *addrs;
|
||||||
/* Number of address ranges in list. */
|
/* Number of address ranges in list. */
|
||||||
@@ -1428,7 +1428,7 @@ resolve_addr_index (const struct dwarf_sections *dwarf_sections,
|
|||||||
uint64_t addr_base, int addrsize, int is_bigendian,
|
uint64_t addr_base, int addrsize, int is_bigendian,
|
||||||
uint64_t addr_index,
|
uint64_t addr_index,
|
||||||
backtrace_error_callback error_callback, void *data,
|
backtrace_error_callback error_callback, void *data,
|
||||||
uint64_t *address)
|
uintptr_t *address)
|
||||||
{
|
{
|
||||||
uint64_t offset;
|
uint64_t offset;
|
||||||
struct dwarf_buf addr_buf;
|
struct dwarf_buf addr_buf;
|
||||||
@@ -1449,7 +1449,7 @@ resolve_addr_index (const struct dwarf_sections *dwarf_sections,
|
|||||||
addr_buf.data = data;
|
addr_buf.data = data;
|
||||||
addr_buf.reported_underflow = 0;
|
addr_buf.reported_underflow = 0;
|
||||||
|
|
||||||
*address = read_address (&addr_buf, addrsize);
|
*address = (uintptr_t) read_address (&addr_buf, addrsize);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1528,7 +1528,7 @@ function_addrs_search (const void *vkey, const void *ventry)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
add_unit_addr (struct backtrace_state *state, void *rdata,
|
add_unit_addr (struct backtrace_state *state, void *rdata,
|
||||||
uint64_t lowpc, uint64_t highpc,
|
uintptr_t lowpc, uintptr_t highpc,
|
||||||
backtrace_error_callback error_callback, void *data,
|
backtrace_error_callback error_callback, void *data,
|
||||||
void *pvec)
|
void *pvec)
|
||||||
{
|
{
|
||||||
@@ -1610,6 +1610,194 @@ unit_addrs_search (const void *vkey, const void *ventry)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fill in overlapping ranges as needed. This is a subroutine of
|
||||||
|
resolve_unit_addrs_overlap. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
resolve_unit_addrs_overlap_walk (struct backtrace_state *state,
|
||||||
|
size_t *pfrom, size_t *pto,
|
||||||
|
struct unit_addrs *enclosing,
|
||||||
|
struct unit_addrs_vector *old_vec,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data,
|
||||||
|
struct unit_addrs_vector *new_vec)
|
||||||
|
{
|
||||||
|
struct unit_addrs *old_addrs;
|
||||||
|
size_t old_count;
|
||||||
|
struct unit_addrs *new_addrs;
|
||||||
|
size_t from;
|
||||||
|
size_t to;
|
||||||
|
|
||||||
|
old_addrs = (struct unit_addrs *) old_vec->vec.base;
|
||||||
|
old_count = old_vec->count;
|
||||||
|
new_addrs = (struct unit_addrs *) new_vec->vec.base;
|
||||||
|
|
||||||
|
for (from = *pfrom, to = *pto; from < old_count; from++, to++)
|
||||||
|
{
|
||||||
|
/* If we are in the scope of a larger range that can no longer
|
||||||
|
cover any further ranges, return back to the caller. */
|
||||||
|
|
||||||
|
if (enclosing != NULL
|
||||||
|
&& enclosing->high <= old_addrs[from].low)
|
||||||
|
{
|
||||||
|
*pfrom = from;
|
||||||
|
*pto = to;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_addrs[to] = old_addrs[from];
|
||||||
|
|
||||||
|
/* If we are in scope of a larger range, fill in any gaps
|
||||||
|
between this entry and the next one.
|
||||||
|
|
||||||
|
There is an extra entry at the end of the vector, so it's
|
||||||
|
always OK to refer to from + 1. */
|
||||||
|
|
||||||
|
if (enclosing != NULL
|
||||||
|
&& enclosing->high > old_addrs[from].high
|
||||||
|
&& old_addrs[from].high < old_addrs[from + 1].low)
|
||||||
|
{
|
||||||
|
void *grew;
|
||||||
|
size_t new_high;
|
||||||
|
|
||||||
|
grew = backtrace_vector_grow (state, sizeof (struct unit_addrs),
|
||||||
|
error_callback, data, &new_vec->vec);
|
||||||
|
if (grew == NULL)
|
||||||
|
return 0;
|
||||||
|
new_addrs = (struct unit_addrs *) new_vec->vec.base;
|
||||||
|
to++;
|
||||||
|
new_addrs[to].low = old_addrs[from].high;
|
||||||
|
new_high = old_addrs[from + 1].low;
|
||||||
|
if (enclosing->high < new_high)
|
||||||
|
new_high = enclosing->high;
|
||||||
|
new_addrs[to].high = new_high;
|
||||||
|
new_addrs[to].u = enclosing->u;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If this range has a larger scope than the next one, use it to
|
||||||
|
fill in any gaps. */
|
||||||
|
|
||||||
|
if (old_addrs[from].high > old_addrs[from + 1].high)
|
||||||
|
{
|
||||||
|
*pfrom = from + 1;
|
||||||
|
*pto = to + 1;
|
||||||
|
if (!resolve_unit_addrs_overlap_walk (state, pfrom, pto,
|
||||||
|
&old_addrs[from], old_vec,
|
||||||
|
error_callback, data, new_vec))
|
||||||
|
return 0;
|
||||||
|
from = *pfrom;
|
||||||
|
to = *pto;
|
||||||
|
|
||||||
|
/* Undo the increment the loop is about to do. */
|
||||||
|
from--;
|
||||||
|
to--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enclosing == NULL)
|
||||||
|
{
|
||||||
|
struct unit_addrs *pa;
|
||||||
|
|
||||||
|
/* Add trailing entry. */
|
||||||
|
|
||||||
|
pa = ((struct unit_addrs *)
|
||||||
|
backtrace_vector_grow (state, sizeof (struct unit_addrs),
|
||||||
|
error_callback, data, &new_vec->vec));
|
||||||
|
if (pa == NULL)
|
||||||
|
return 0;
|
||||||
|
pa->low = 0;
|
||||||
|
--pa->low;
|
||||||
|
pa->high = pa->low;
|
||||||
|
pa->u = NULL;
|
||||||
|
|
||||||
|
new_vec->count = to;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* It is possible for the unit_addrs list to contain overlaps, as in
|
||||||
|
|
||||||
|
10: low == 10, high == 20, unit 1
|
||||||
|
11: low == 12, high == 15, unit 2
|
||||||
|
12: low == 20, high == 30, unit 1
|
||||||
|
|
||||||
|
In such a case, for pc == 17, a search using units_addr_search will
|
||||||
|
return entry 11. However, pc == 17 doesn't fit in that range. We
|
||||||
|
actually want range 10.
|
||||||
|
|
||||||
|
It seems that in general we might have an arbitrary number of
|
||||||
|
ranges in between 10 and 12.
|
||||||
|
|
||||||
|
To handle this we look for cases where range R1 is followed by
|
||||||
|
range R2 such that R2 is a strict subset of R1. In such cases we
|
||||||
|
insert a new range R3 following R2 that fills in the remainder of
|
||||||
|
the address space covered by R1. That lets a relatively simple
|
||||||
|
search find the correct range.
|
||||||
|
|
||||||
|
These overlaps can occur because of the range merging we do in
|
||||||
|
add_unit_addr. When the linker de-duplicates functions, it can
|
||||||
|
leave behind an address range that refers to the address range of
|
||||||
|
the retained duplicate. If the retained duplicate address range is
|
||||||
|
merged with others, then after sorting we can see overlapping
|
||||||
|
address ranges.
|
||||||
|
|
||||||
|
See https://github.com/ianlancetaylor/libbacktrace/issues/137. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
resolve_unit_addrs_overlap (struct backtrace_state *state,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data, struct unit_addrs_vector *addrs_vec)
|
||||||
|
{
|
||||||
|
struct unit_addrs *addrs;
|
||||||
|
size_t count;
|
||||||
|
int found;
|
||||||
|
struct unit_addrs *entry;
|
||||||
|
size_t i;
|
||||||
|
struct unit_addrs_vector new_vec;
|
||||||
|
void *grew;
|
||||||
|
size_t from;
|
||||||
|
size_t to;
|
||||||
|
|
||||||
|
addrs = (struct unit_addrs *) addrs_vec->vec.base;
|
||||||
|
count = addrs_vec->count;
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Optimistically assume that overlaps are rare. */
|
||||||
|
found = 0;
|
||||||
|
entry = addrs;
|
||||||
|
for (i = 0; i < count - 1; i++)
|
||||||
|
{
|
||||||
|
if (entry->low < (entry + 1)->low
|
||||||
|
&& entry->high > (entry + 1)->high)
|
||||||
|
{
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
entry++;
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
memset (&new_vec, 0, sizeof new_vec);
|
||||||
|
grew = backtrace_vector_grow (state,
|
||||||
|
count * sizeof (struct unit_addrs),
|
||||||
|
error_callback, data, &new_vec.vec);
|
||||||
|
if (grew == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
from = 0;
|
||||||
|
to = 0;
|
||||||
|
resolve_unit_addrs_overlap_walk (state, &from, &to, NULL, addrs_vec,
|
||||||
|
error_callback, data, &new_vec);
|
||||||
|
backtrace_vector_free (state, &addrs_vec->vec, error_callback, data);
|
||||||
|
*addrs_vec = new_vec;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Sort the line vector by PC. We want a stable sort here to maintain
|
/* Sort the line vector by PC. We want a stable sort here to maintain
|
||||||
the order of lines for the same PC values. Since the sequence is
|
the order of lines for the same PC values. Since the sequence is
|
||||||
being sorted in place, their addresses cannot be relied on to
|
being sorted in place, their addresses cannot be relied on to
|
||||||
@@ -1864,10 +2052,10 @@ lookup_abbrev (struct abbrevs *abbrevs, uint64_t code,
|
|||||||
lowpc/highpc is set or ranges is set. */
|
lowpc/highpc is set or ranges is set. */
|
||||||
|
|
||||||
struct pcrange {
|
struct pcrange {
|
||||||
uint64_t lowpc; /* The low PC value. */
|
uintptr_t lowpc; /* The low PC value. */
|
||||||
int have_lowpc; /* Whether a low PC value was found. */
|
int have_lowpc; /* Whether a low PC value was found. */
|
||||||
int lowpc_is_addr_index; /* Whether lowpc is in .debug_addr. */
|
int lowpc_is_addr_index; /* Whether lowpc is in .debug_addr. */
|
||||||
uint64_t highpc; /* The high PC value. */
|
uintptr_t highpc; /* The high PC value. */
|
||||||
int have_highpc; /* Whether a high PC value was found. */
|
int have_highpc; /* Whether a high PC value was found. */
|
||||||
int highpc_is_relative; /* Whether highpc is relative to lowpc. */
|
int highpc_is_relative; /* Whether highpc is relative to lowpc. */
|
||||||
int highpc_is_addr_index; /* Whether highpc is in .debug_addr. */
|
int highpc_is_addr_index; /* Whether highpc is in .debug_addr. */
|
||||||
@@ -1887,12 +2075,12 @@ update_pcrange (const struct attr* attr, const struct attr_val* val,
|
|||||||
case DW_AT_low_pc:
|
case DW_AT_low_pc:
|
||||||
if (val->encoding == ATTR_VAL_ADDRESS)
|
if (val->encoding == ATTR_VAL_ADDRESS)
|
||||||
{
|
{
|
||||||
pcrange->lowpc = val->u.uint;
|
pcrange->lowpc = (uintptr_t) val->u.uint;
|
||||||
pcrange->have_lowpc = 1;
|
pcrange->have_lowpc = 1;
|
||||||
}
|
}
|
||||||
else if (val->encoding == ATTR_VAL_ADDRESS_INDEX)
|
else if (val->encoding == ATTR_VAL_ADDRESS_INDEX)
|
||||||
{
|
{
|
||||||
pcrange->lowpc = val->u.uint;
|
pcrange->lowpc = (uintptr_t) val->u.uint;
|
||||||
pcrange->have_lowpc = 1;
|
pcrange->have_lowpc = 1;
|
||||||
pcrange->lowpc_is_addr_index = 1;
|
pcrange->lowpc_is_addr_index = 1;
|
||||||
}
|
}
|
||||||
@@ -1901,18 +2089,18 @@ update_pcrange (const struct attr* attr, const struct attr_val* val,
|
|||||||
case DW_AT_high_pc:
|
case DW_AT_high_pc:
|
||||||
if (val->encoding == ATTR_VAL_ADDRESS)
|
if (val->encoding == ATTR_VAL_ADDRESS)
|
||||||
{
|
{
|
||||||
pcrange->highpc = val->u.uint;
|
pcrange->highpc = (uintptr_t) val->u.uint;
|
||||||
pcrange->have_highpc = 1;
|
pcrange->have_highpc = 1;
|
||||||
}
|
}
|
||||||
else if (val->encoding == ATTR_VAL_UINT)
|
else if (val->encoding == ATTR_VAL_UINT)
|
||||||
{
|
{
|
||||||
pcrange->highpc = val->u.uint;
|
pcrange->highpc = (uintptr_t) val->u.uint;
|
||||||
pcrange->have_highpc = 1;
|
pcrange->have_highpc = 1;
|
||||||
pcrange->highpc_is_relative = 1;
|
pcrange->highpc_is_relative = 1;
|
||||||
}
|
}
|
||||||
else if (val->encoding == ATTR_VAL_ADDRESS_INDEX)
|
else if (val->encoding == ATTR_VAL_ADDRESS_INDEX)
|
||||||
{
|
{
|
||||||
pcrange->highpc = val->u.uint;
|
pcrange->highpc = (uintptr_t) val->u.uint;
|
||||||
pcrange->have_highpc = 1;
|
pcrange->have_highpc = 1;
|
||||||
pcrange->highpc_is_addr_index = 1;
|
pcrange->highpc_is_addr_index = 1;
|
||||||
}
|
}
|
||||||
@@ -1944,19 +2132,20 @@ update_pcrange (const struct attr* attr, const struct attr_val* val,
|
|||||||
static int
|
static int
|
||||||
add_low_high_range (struct backtrace_state *state,
|
add_low_high_range (struct backtrace_state *state,
|
||||||
const struct dwarf_sections *dwarf_sections,
|
const struct dwarf_sections *dwarf_sections,
|
||||||
uintptr_t base_address, int is_bigendian,
|
struct libbacktrace_base_address base_address,
|
||||||
struct unit *u, const struct pcrange *pcrange,
|
int is_bigendian, struct unit *u,
|
||||||
|
const struct pcrange *pcrange,
|
||||||
int (*add_range) (struct backtrace_state *state,
|
int (*add_range) (struct backtrace_state *state,
|
||||||
void *rdata, uint64_t lowpc,
|
void *rdata, uintptr_t lowpc,
|
||||||
uint64_t highpc,
|
uintptr_t highpc,
|
||||||
backtrace_error_callback error_callback,
|
backtrace_error_callback error_callback,
|
||||||
void *data, void *vec),
|
void *data, void *vec),
|
||||||
void *rdata,
|
void *rdata,
|
||||||
backtrace_error_callback error_callback, void *data,
|
backtrace_error_callback error_callback, void *data,
|
||||||
void *vec)
|
void *vec)
|
||||||
{
|
{
|
||||||
uint64_t lowpc;
|
uintptr_t lowpc;
|
||||||
uint64_t highpc;
|
uintptr_t highpc;
|
||||||
|
|
||||||
lowpc = pcrange->lowpc;
|
lowpc = pcrange->lowpc;
|
||||||
if (pcrange->lowpc_is_addr_index)
|
if (pcrange->lowpc_is_addr_index)
|
||||||
@@ -1980,8 +2169,8 @@ add_low_high_range (struct backtrace_state *state,
|
|||||||
|
|
||||||
/* Add in the base address of the module when recording PC values,
|
/* Add in the base address of the module when recording PC values,
|
||||||
so that we can look up the PC directly. */
|
so that we can look up the PC directly. */
|
||||||
lowpc += base_address;
|
lowpc = libbacktrace_add_base (lowpc, base_address);
|
||||||
highpc += base_address;
|
highpc = libbacktrace_add_base (highpc, base_address);
|
||||||
|
|
||||||
return add_range (state, rdata, lowpc, highpc, error_callback, data, vec);
|
return add_range (state, rdata, lowpc, highpc, error_callback, data, vec);
|
||||||
}
|
}
|
||||||
@@ -1993,11 +2182,11 @@ static int
|
|||||||
add_ranges_from_ranges (
|
add_ranges_from_ranges (
|
||||||
struct backtrace_state *state,
|
struct backtrace_state *state,
|
||||||
const struct dwarf_sections *dwarf_sections,
|
const struct dwarf_sections *dwarf_sections,
|
||||||
uintptr_t base_address, int is_bigendian,
|
struct libbacktrace_base_address base_address, int is_bigendian,
|
||||||
struct unit *u, uint64_t base,
|
struct unit *u, uintptr_t base,
|
||||||
const struct pcrange *pcrange,
|
const struct pcrange *pcrange,
|
||||||
int (*add_range) (struct backtrace_state *state, void *rdata,
|
int (*add_range) (struct backtrace_state *state, void *rdata,
|
||||||
uint64_t lowpc, uint64_t highpc,
|
uintptr_t lowpc, uintptr_t highpc,
|
||||||
backtrace_error_callback error_callback, void *data,
|
backtrace_error_callback error_callback, void *data,
|
||||||
void *vec),
|
void *vec),
|
||||||
void *rdata,
|
void *rdata,
|
||||||
@@ -2036,13 +2225,14 @@ add_ranges_from_ranges (
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
if (is_highest_address (low, u->addrsize))
|
if (is_highest_address (low, u->addrsize))
|
||||||
base = high;
|
base = (uintptr_t) high;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!add_range (state, rdata,
|
uintptr_t rl, rh;
|
||||||
low + base + base_address,
|
|
||||||
high + base + base_address,
|
rl = libbacktrace_add_base ((uintptr_t) low + base, base_address);
|
||||||
error_callback, data, vec))
|
rh = libbacktrace_add_base ((uintptr_t) high + base, base_address);
|
||||||
|
if (!add_range (state, rdata, rl, rh, error_callback, data, vec))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2060,11 +2250,11 @@ static int
|
|||||||
add_ranges_from_rnglists (
|
add_ranges_from_rnglists (
|
||||||
struct backtrace_state *state,
|
struct backtrace_state *state,
|
||||||
const struct dwarf_sections *dwarf_sections,
|
const struct dwarf_sections *dwarf_sections,
|
||||||
uintptr_t base_address, int is_bigendian,
|
struct libbacktrace_base_address base_address, int is_bigendian,
|
||||||
struct unit *u, uint64_t base,
|
struct unit *u, uintptr_t base,
|
||||||
const struct pcrange *pcrange,
|
const struct pcrange *pcrange,
|
||||||
int (*add_range) (struct backtrace_state *state, void *rdata,
|
int (*add_range) (struct backtrace_state *state, void *rdata,
|
||||||
uint64_t lowpc, uint64_t highpc,
|
uintptr_t lowpc, uintptr_t highpc,
|
||||||
backtrace_error_callback error_callback, void *data,
|
backtrace_error_callback error_callback, void *data,
|
||||||
void *vec),
|
void *vec),
|
||||||
void *rdata,
|
void *rdata,
|
||||||
@@ -2130,8 +2320,8 @@ add_ranges_from_rnglists (
|
|||||||
case DW_RLE_startx_endx:
|
case DW_RLE_startx_endx:
|
||||||
{
|
{
|
||||||
uint64_t index;
|
uint64_t index;
|
||||||
uint64_t low;
|
uintptr_t low;
|
||||||
uint64_t high;
|
uintptr_t high;
|
||||||
|
|
||||||
index = read_uleb128 (&rnglists_buf);
|
index = read_uleb128 (&rnglists_buf);
|
||||||
if (!resolve_addr_index (dwarf_sections, u->addr_base,
|
if (!resolve_addr_index (dwarf_sections, u->addr_base,
|
||||||
@@ -2143,9 +2333,10 @@ add_ranges_from_rnglists (
|
|||||||
u->addrsize, is_bigendian, index,
|
u->addrsize, is_bigendian, index,
|
||||||
error_callback, data, &high))
|
error_callback, data, &high))
|
||||||
return 0;
|
return 0;
|
||||||
if (!add_range (state, rdata, low + base_address,
|
if (!add_range (state, rdata,
|
||||||
high + base_address, error_callback, data,
|
libbacktrace_add_base (low, base_address),
|
||||||
vec))
|
libbacktrace_add_base (high, base_address),
|
||||||
|
error_callback, data, vec))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -2153,8 +2344,8 @@ add_ranges_from_rnglists (
|
|||||||
case DW_RLE_startx_length:
|
case DW_RLE_startx_length:
|
||||||
{
|
{
|
||||||
uint64_t index;
|
uint64_t index;
|
||||||
uint64_t low;
|
uintptr_t low;
|
||||||
uint64_t length;
|
uintptr_t length;
|
||||||
|
|
||||||
index = read_uleb128 (&rnglists_buf);
|
index = read_uleb128 (&rnglists_buf);
|
||||||
if (!resolve_addr_index (dwarf_sections, u->addr_base,
|
if (!resolve_addr_index (dwarf_sections, u->addr_base,
|
||||||
@@ -2162,7 +2353,7 @@ add_ranges_from_rnglists (
|
|||||||
error_callback, data, &low))
|
error_callback, data, &low))
|
||||||
return 0;
|
return 0;
|
||||||
length = read_uleb128 (&rnglists_buf);
|
length = read_uleb128 (&rnglists_buf);
|
||||||
low += base_address;
|
low = libbacktrace_add_base (low, base_address);
|
||||||
if (!add_range (state, rdata, low, low + length,
|
if (!add_range (state, rdata, low, low + length,
|
||||||
error_callback, data, vec))
|
error_callback, data, vec))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -2176,39 +2367,41 @@ add_ranges_from_rnglists (
|
|||||||
|
|
||||||
low = read_uleb128 (&rnglists_buf);
|
low = read_uleb128 (&rnglists_buf);
|
||||||
high = read_uleb128 (&rnglists_buf);
|
high = read_uleb128 (&rnglists_buf);
|
||||||
if (!add_range (state, rdata, low + base + base_address,
|
if (!add_range (state, rdata,
|
||||||
high + base + base_address,
|
libbacktrace_add_base (low + base, base_address),
|
||||||
|
libbacktrace_add_base (high + base, base_address),
|
||||||
error_callback, data, vec))
|
error_callback, data, vec))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_RLE_base_address:
|
case DW_RLE_base_address:
|
||||||
base = read_address (&rnglists_buf, u->addrsize);
|
base = (uintptr_t) read_address (&rnglists_buf, u->addrsize);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_RLE_start_end:
|
case DW_RLE_start_end:
|
||||||
{
|
{
|
||||||
uint64_t low;
|
uintptr_t low;
|
||||||
uint64_t high;
|
uintptr_t high;
|
||||||
|
|
||||||
low = read_address (&rnglists_buf, u->addrsize);
|
low = (uintptr_t) read_address (&rnglists_buf, u->addrsize);
|
||||||
high = read_address (&rnglists_buf, u->addrsize);
|
high = (uintptr_t) read_address (&rnglists_buf, u->addrsize);
|
||||||
if (!add_range (state, rdata, low + base_address,
|
if (!add_range (state, rdata,
|
||||||
high + base_address, error_callback, data,
|
libbacktrace_add_base (low, base_address),
|
||||||
vec))
|
libbacktrace_add_base (high, base_address),
|
||||||
|
error_callback, data, vec))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_RLE_start_length:
|
case DW_RLE_start_length:
|
||||||
{
|
{
|
||||||
uint64_t low;
|
uintptr_t low;
|
||||||
uint64_t length;
|
uintptr_t length;
|
||||||
|
|
||||||
low = read_address (&rnglists_buf, u->addrsize);
|
low = (uintptr_t) read_address (&rnglists_buf, u->addrsize);
|
||||||
length = read_uleb128 (&rnglists_buf);
|
length = (uintptr_t) read_uleb128 (&rnglists_buf);
|
||||||
low += base_address;
|
low = libbacktrace_add_base (low, base_address);
|
||||||
if (!add_range (state, rdata, low, low + length,
|
if (!add_range (state, rdata, low, low + length,
|
||||||
error_callback, data, vec))
|
error_callback, data, vec))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -2236,10 +2429,10 @@ add_ranges_from_rnglists (
|
|||||||
static int
|
static int
|
||||||
add_ranges (struct backtrace_state *state,
|
add_ranges (struct backtrace_state *state,
|
||||||
const struct dwarf_sections *dwarf_sections,
|
const struct dwarf_sections *dwarf_sections,
|
||||||
uintptr_t base_address, int is_bigendian,
|
struct libbacktrace_base_address base_address, int is_bigendian,
|
||||||
struct unit *u, uint64_t base, const struct pcrange *pcrange,
|
struct unit *u, uintptr_t base, const struct pcrange *pcrange,
|
||||||
int (*add_range) (struct backtrace_state *state, void *rdata,
|
int (*add_range) (struct backtrace_state *state, void *rdata,
|
||||||
uint64_t lowpc, uint64_t highpc,
|
uintptr_t lowpc, uintptr_t highpc,
|
||||||
backtrace_error_callback error_callback,
|
backtrace_error_callback error_callback,
|
||||||
void *data, void *vec),
|
void *data, void *vec),
|
||||||
void *rdata,
|
void *rdata,
|
||||||
@@ -2272,7 +2465,8 @@ add_ranges (struct backtrace_state *state,
|
|||||||
read, 0 if there is some error. */
|
read, 0 if there is some error. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
|
find_address_ranges (struct backtrace_state *state,
|
||||||
|
struct libbacktrace_base_address base_address,
|
||||||
struct dwarf_buf *unit_buf,
|
struct dwarf_buf *unit_buf,
|
||||||
const struct dwarf_sections *dwarf_sections,
|
const struct dwarf_sections *dwarf_sections,
|
||||||
int is_bigendian, struct dwarf_data *altlink,
|
int is_bigendian, struct dwarf_data *altlink,
|
||||||
@@ -2427,7 +2621,8 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
|
|||||||
on success, 0 on failure. */
|
on success, 0 on failure. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
build_address_map (struct backtrace_state *state, uintptr_t base_address,
|
build_address_map (struct backtrace_state *state,
|
||||||
|
struct libbacktrace_base_address base_address,
|
||||||
const struct dwarf_sections *dwarf_sections,
|
const struct dwarf_sections *dwarf_sections,
|
||||||
int is_bigendian, struct dwarf_data *altlink,
|
int is_bigendian, struct dwarf_data *altlink,
|
||||||
backtrace_error_callback error_callback, void *data,
|
backtrace_error_callback error_callback, void *data,
|
||||||
@@ -2646,7 +2841,7 @@ add_line (struct backtrace_state *state, struct dwarf_data *ddata,
|
|||||||
|
|
||||||
/* Add in the base address here, so that we can look up the PC
|
/* Add in the base address here, so that we can look up the PC
|
||||||
directly. */
|
directly. */
|
||||||
ln->pc = pc + ddata->base_address;
|
ln->pc = libbacktrace_add_base (pc, ddata->base_address);
|
||||||
|
|
||||||
ln->filename = filename;
|
ln->filename = filename;
|
||||||
ln->lineno = lineno;
|
ln->lineno = lineno;
|
||||||
@@ -3307,7 +3502,7 @@ read_line_info (struct backtrace_state *state, struct dwarf_data *ddata,
|
|||||||
|
|
||||||
if (vec.count == 0)
|
if (vec.count == 0)
|
||||||
{
|
{
|
||||||
/* This is not a failure in the sense of a generating an error,
|
/* This is not a failure in the sense of generating an error,
|
||||||
but it is a failure in that sense that we have no useful
|
but it is a failure in that sense that we have no useful
|
||||||
information. */
|
information. */
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -3517,7 +3712,7 @@ read_referenced_name (struct dwarf_data *ddata, struct unit *u,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
add_function_range (struct backtrace_state *state, void *rdata,
|
add_function_range (struct backtrace_state *state, void *rdata,
|
||||||
uint64_t lowpc, uint64_t highpc,
|
uintptr_t lowpc, uintptr_t highpc,
|
||||||
backtrace_error_callback error_callback, void *data,
|
backtrace_error_callback error_callback, void *data,
|
||||||
void *pvec)
|
void *pvec)
|
||||||
{
|
{
|
||||||
@@ -3557,7 +3752,7 @@ add_function_range (struct backtrace_state *state, void *rdata,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata,
|
read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata,
|
||||||
struct unit *u, uint64_t base, struct dwarf_buf *unit_buf,
|
struct unit *u, uintptr_t base, struct dwarf_buf *unit_buf,
|
||||||
const struct line_header *lhdr,
|
const struct line_header *lhdr,
|
||||||
backtrace_error_callback error_callback, void *data,
|
backtrace_error_callback error_callback, void *data,
|
||||||
struct function_vector *vec_function,
|
struct function_vector *vec_function,
|
||||||
@@ -3621,7 +3816,7 @@ read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata,
|
|||||||
&& abbrev->attrs[i].name == DW_AT_low_pc)
|
&& abbrev->attrs[i].name == DW_AT_low_pc)
|
||||||
{
|
{
|
||||||
if (val.encoding == ATTR_VAL_ADDRESS)
|
if (val.encoding == ATTR_VAL_ADDRESS)
|
||||||
base = val.u.uint;
|
base = (uintptr_t) val.u.uint;
|
||||||
else if (val.encoding == ATTR_VAL_ADDRESS_INDEX)
|
else if (val.encoding == ATTR_VAL_ADDRESS_INDEX)
|
||||||
{
|
{
|
||||||
if (!resolve_addr_index (&ddata->dwarf_sections,
|
if (!resolve_addr_index (&ddata->dwarf_sections,
|
||||||
@@ -4285,7 +4480,7 @@ dwarf_fileline (struct backtrace_state *state, uintptr_t pc,
|
|||||||
|
|
||||||
static struct dwarf_data *
|
static struct dwarf_data *
|
||||||
build_dwarf_data (struct backtrace_state *state,
|
build_dwarf_data (struct backtrace_state *state,
|
||||||
uintptr_t base_address,
|
struct libbacktrace_base_address base_address,
|
||||||
const struct dwarf_sections *dwarf_sections,
|
const struct dwarf_sections *dwarf_sections,
|
||||||
int is_bigendian,
|
int is_bigendian,
|
||||||
struct dwarf_data *altlink,
|
struct dwarf_data *altlink,
|
||||||
@@ -4293,11 +4488,7 @@ build_dwarf_data (struct backtrace_state *state,
|
|||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct unit_addrs_vector addrs_vec;
|
struct unit_addrs_vector addrs_vec;
|
||||||
struct unit_addrs *addrs;
|
|
||||||
size_t addrs_count;
|
|
||||||
struct unit_vector units_vec;
|
struct unit_vector units_vec;
|
||||||
struct unit **units;
|
|
||||||
size_t units_count;
|
|
||||||
struct dwarf_data *fdata;
|
struct dwarf_data *fdata;
|
||||||
|
|
||||||
if (!build_address_map (state, base_address, dwarf_sections, is_bigendian,
|
if (!build_address_map (state, base_address, dwarf_sections, is_bigendian,
|
||||||
@@ -4309,12 +4500,12 @@ build_dwarf_data (struct backtrace_state *state,
|
|||||||
return NULL;
|
return NULL;
|
||||||
if (!backtrace_vector_release (state, &units_vec.vec, error_callback, data))
|
if (!backtrace_vector_release (state, &units_vec.vec, error_callback, data))
|
||||||
return NULL;
|
return NULL;
|
||||||
addrs = (struct unit_addrs *) addrs_vec.vec.base;
|
|
||||||
units = (struct unit **) units_vec.vec.base;
|
backtrace_qsort ((struct unit_addrs *) addrs_vec.vec.base, addrs_vec.count,
|
||||||
addrs_count = addrs_vec.count;
|
sizeof (struct unit_addrs), unit_addrs_compare);
|
||||||
units_count = units_vec.count;
|
if (!resolve_unit_addrs_overlap (state, error_callback, data, &addrs_vec))
|
||||||
backtrace_qsort (addrs, addrs_count, sizeof (struct unit_addrs),
|
return NULL;
|
||||||
unit_addrs_compare);
|
|
||||||
/* No qsort for units required, already sorted. */
|
/* No qsort for units required, already sorted. */
|
||||||
|
|
||||||
fdata = ((struct dwarf_data *)
|
fdata = ((struct dwarf_data *)
|
||||||
@@ -4326,10 +4517,10 @@ build_dwarf_data (struct backtrace_state *state,
|
|||||||
fdata->next = NULL;
|
fdata->next = NULL;
|
||||||
fdata->altlink = altlink;
|
fdata->altlink = altlink;
|
||||||
fdata->base_address = base_address;
|
fdata->base_address = base_address;
|
||||||
fdata->addrs = addrs;
|
fdata->addrs = (struct unit_addrs *) addrs_vec.vec.base;
|
||||||
fdata->addrs_count = addrs_count;
|
fdata->addrs_count = addrs_vec.count;
|
||||||
fdata->units = units;
|
fdata->units = (struct unit **) units_vec.vec.base;
|
||||||
fdata->units_count = units_count;
|
fdata->units_count = units_vec.count;
|
||||||
fdata->dwarf_sections = *dwarf_sections;
|
fdata->dwarf_sections = *dwarf_sections;
|
||||||
fdata->is_bigendian = is_bigendian;
|
fdata->is_bigendian = is_bigendian;
|
||||||
memset (&fdata->fvec, 0, sizeof fdata->fvec);
|
memset (&fdata->fvec, 0, sizeof fdata->fvec);
|
||||||
@@ -4343,7 +4534,7 @@ build_dwarf_data (struct backtrace_state *state,
|
|||||||
|
|
||||||
int
|
int
|
||||||
backtrace_dwarf_add (struct backtrace_state *state,
|
backtrace_dwarf_add (struct backtrace_state *state,
|
||||||
uintptr_t base_address,
|
struct libbacktrace_base_address base_address,
|
||||||
const struct dwarf_sections *dwarf_sections,
|
const struct dwarf_sections *dwarf_sections,
|
||||||
int is_bigendian,
|
int is_bigendian,
|
||||||
struct dwarf_data *fileline_altlink,
|
struct dwarf_data *fileline_altlink,
|
||||||
|
|||||||
77
thirdparty/libbacktrace/fileline.c
vendored
77
thirdparty/libbacktrace/fileline.c
vendored
@@ -1,5 +1,5 @@
|
|||||||
/* fileline.c -- Get file and line number information in a backtrace.
|
/* fileline.c -- Get file and line number information in a backtrace.
|
||||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
Copyright (C) 2012-2024 Free Software Foundation, Inc.
|
||||||
Written by Ian Lance Taylor, Google.
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -47,6 +47,18 @@ POSSIBILITY OF SUCH DAMAGE. */
|
|||||||
#include <mach-o/dyld.h>
|
#include <mach-o/dyld.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NOMINMAX
|
||||||
|
#define NOMINMAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "backtrace.h"
|
#include "backtrace.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@@ -155,6 +167,47 @@ macho_get_executable_path (struct backtrace_state *state,
|
|||||||
|
|
||||||
#endif /* !defined (HAVE_MACH_O_DYLD_H) */
|
#endif /* !defined (HAVE_MACH_O_DYLD_H) */
|
||||||
|
|
||||||
|
#if HAVE_DECL__PGMPTR
|
||||||
|
|
||||||
|
#define windows_executable_filename() _pgmptr
|
||||||
|
|
||||||
|
#else /* !HAVE_DECL__PGMPTR */
|
||||||
|
|
||||||
|
#define windows_executable_filename() NULL
|
||||||
|
|
||||||
|
#endif /* !HAVE_DECL__PGMPTR */
|
||||||
|
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
|
||||||
|
#define FILENAME_BUF_SIZE (MAX_PATH)
|
||||||
|
|
||||||
|
static char *
|
||||||
|
windows_get_executable_path (char *buf, backtrace_error_callback error_callback,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
size_t got;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
got = GetModuleFileNameA (NULL, buf, FILENAME_BUF_SIZE - 1);
|
||||||
|
error = GetLastError ();
|
||||||
|
if (got == 0
|
||||||
|
|| (got == FILENAME_BUF_SIZE - 1 && error == ERROR_INSUFFICIENT_BUFFER))
|
||||||
|
{
|
||||||
|
error_callback (data,
|
||||||
|
"could not get the filename of the current executable",
|
||||||
|
error);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* !defined (HAVE_WINDOWS_H) */
|
||||||
|
|
||||||
|
#define windows_get_executable_path(buf, error_callback, data) NULL
|
||||||
|
#define FILENAME_BUF_SIZE 64
|
||||||
|
|
||||||
|
#endif /* !defined (HAVE_WINDOWS_H) */
|
||||||
|
|
||||||
/* Initialize the fileline information from the executable. Returns 1
|
/* Initialize the fileline information from the executable. Returns 1
|
||||||
on success, 0 on failure. */
|
on success, 0 on failure. */
|
||||||
|
|
||||||
@@ -168,7 +221,7 @@ fileline_initialize (struct backtrace_state *state,
|
|||||||
int called_error_callback;
|
int called_error_callback;
|
||||||
int descriptor;
|
int descriptor;
|
||||||
const char *filename;
|
const char *filename;
|
||||||
char buf[64];
|
char buf[FILENAME_BUF_SIZE];
|
||||||
|
|
||||||
if (!state->threaded)
|
if (!state->threaded)
|
||||||
failed = state->fileline_initialization_failed;
|
failed = state->fileline_initialization_failed;
|
||||||
@@ -192,7 +245,7 @@ fileline_initialize (struct backtrace_state *state,
|
|||||||
|
|
||||||
descriptor = -1;
|
descriptor = -1;
|
||||||
called_error_callback = 0;
|
called_error_callback = 0;
|
||||||
for (pass = 0; pass < 8; ++pass)
|
for (pass = 0; pass < 10; ++pass)
|
||||||
{
|
{
|
||||||
int does_not_exist;
|
int does_not_exist;
|
||||||
|
|
||||||
@@ -205,25 +258,33 @@ fileline_initialize (struct backtrace_state *state,
|
|||||||
filename = getexecname ();
|
filename = getexecname ();
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
filename = "/proc/self/exe";
|
/* Test this before /proc/self/exe, as the latter exists but points
|
||||||
|
to the wine binary (and thus doesn't work). */
|
||||||
|
filename = windows_executable_filename ();
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
filename = "/proc/curproc/file";
|
filename = "/proc/self/exe";
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
|
filename = "/proc/curproc/file";
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
snprintf (buf, sizeof (buf), "/proc/%ld/object/a.out",
|
snprintf (buf, sizeof (buf), "/proc/%ld/object/a.out",
|
||||||
(long) getpid ());
|
(long) getpid ());
|
||||||
filename = buf;
|
filename = buf;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 6:
|
||||||
filename = sysctl_exec_name1 (state, error_callback, data);
|
filename = sysctl_exec_name1 (state, error_callback, data);
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 7:
|
||||||
filename = sysctl_exec_name2 (state, error_callback, data);
|
filename = sysctl_exec_name2 (state, error_callback, data);
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 8:
|
||||||
filename = macho_get_executable_path (state, error_callback, data);
|
filename = macho_get_executable_path (state, error_callback, data);
|
||||||
break;
|
break;
|
||||||
|
case 9:
|
||||||
|
filename = windows_get_executable_path (buf, error_callback, data);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
|
|||||||
52
thirdparty/libbacktrace/internal.h
vendored
52
thirdparty/libbacktrace/internal.h
vendored
@@ -1,5 +1,5 @@
|
|||||||
/* internal.h -- Internal header file for stack backtrace library.
|
/* internal.h -- Internal header file for stack backtrace library.
|
||||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
Copyright (C) 2012-2024 Free Software Foundation, Inc.
|
||||||
Written by Ian Lance Taylor, Google.
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -56,6 +56,11 @@ POSSIBILITY OF SUCH DAMAGE. */
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __has_attribute
|
||||||
|
# if __has_attribute(fallthrough)
|
||||||
|
# define ATTRIBUTE_FALLTHROUGH __attribute__ ((fallthrough))
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
#ifndef ATTRIBUTE_FALLTHROUGH
|
#ifndef ATTRIBUTE_FALLTHROUGH
|
||||||
# if (GCC_VERSION >= 7000)
|
# if (GCC_VERSION >= 7000)
|
||||||
# define ATTRIBUTE_FALLTHROUGH __attribute__ ((__fallthrough__))
|
# define ATTRIBUTE_FALLTHROUGH __attribute__ ((__fallthrough__))
|
||||||
@@ -323,10 +328,44 @@ struct dwarf_sections
|
|||||||
|
|
||||||
struct dwarf_data;
|
struct dwarf_data;
|
||||||
|
|
||||||
|
/* The load address mapping. */
|
||||||
|
|
||||||
|
#if defined(__FDPIC__) && defined(HAVE_DL_ITERATE_PHDR) && (defined(HAVE_LINK_H) || defined(HAVE_SYS_LINK_H))
|
||||||
|
|
||||||
|
#ifdef HAVE_LINK_H
|
||||||
|
#include <link.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_LINK_H
|
||||||
|
#include <sys/link.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define libbacktrace_using_fdpic() (1)
|
||||||
|
|
||||||
|
struct libbacktrace_base_address
|
||||||
|
{
|
||||||
|
struct elf32_fdpic_loadaddr m;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define libbacktrace_add_base(pc, base) \
|
||||||
|
((uintptr_t) (__RELOC_POINTER ((pc), (base).m)))
|
||||||
|
|
||||||
|
#else /* not _FDPIC__ */
|
||||||
|
|
||||||
|
#define libbacktrace_using_fdpic() (0)
|
||||||
|
|
||||||
|
struct libbacktrace_base_address
|
||||||
|
{
|
||||||
|
uintptr_t m;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define libbacktrace_add_base(pc, base) ((pc) + (base).m)
|
||||||
|
|
||||||
|
#endif /* not _FDPIC__ */
|
||||||
|
|
||||||
/* Add file/line information for a DWARF module. */
|
/* Add file/line information for a DWARF module. */
|
||||||
|
|
||||||
extern int backtrace_dwarf_add (struct backtrace_state *state,
|
extern int backtrace_dwarf_add (struct backtrace_state *state,
|
||||||
uintptr_t base_address,
|
struct libbacktrace_base_address base_address,
|
||||||
const struct dwarf_sections *dwarf_sections,
|
const struct dwarf_sections *dwarf_sections,
|
||||||
int is_bigendian,
|
int is_bigendian,
|
||||||
struct dwarf_data *fileline_altlink,
|
struct dwarf_data *fileline_altlink,
|
||||||
@@ -368,6 +407,15 @@ extern int backtrace_uncompress_zdebug (struct backtrace_state *,
|
|||||||
unsigned char **uncompressed,
|
unsigned char **uncompressed,
|
||||||
size_t *uncompressed_size);
|
size_t *uncompressed_size);
|
||||||
|
|
||||||
|
/* A test-only hook for elf_zstd_decompress. */
|
||||||
|
|
||||||
|
extern int backtrace_uncompress_zstd (struct backtrace_state *,
|
||||||
|
const unsigned char *compressed,
|
||||||
|
size_t compressed_size,
|
||||||
|
backtrace_error_callback, void *data,
|
||||||
|
unsigned char *uncompressed,
|
||||||
|
size_t uncompressed_size);
|
||||||
|
|
||||||
/* A test-only hook for elf_uncompress_lzma. */
|
/* A test-only hook for elf_uncompress_lzma. */
|
||||||
|
|
||||||
extern int backtrace_uncompress_lzma (struct backtrace_state *,
|
extern int backtrace_uncompress_lzma (struct backtrace_state *,
|
||||||
|
|||||||
228
thirdparty/libbacktrace/pecoff.c
vendored
228
thirdparty/libbacktrace/pecoff.c
vendored
@@ -1,5 +1,5 @@
|
|||||||
/* pecoff.c -- Get debug data from a PE/COFFF file for backtraces.
|
/* pecoff.c -- Get debug data from a PE/COFFF file for backtraces.
|
||||||
Copyright (C) 2015-2021 Free Software Foundation, Inc.
|
Copyright (C) 2015-2024 Free Software Foundation, Inc.
|
||||||
Adapted from elf.c by Tristan Gingold, AdaCore.
|
Adapted from elf.c by Tristan Gingold, AdaCore.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -39,6 +39,58 @@ POSSIBILITY OF SUCH DAMAGE. */
|
|||||||
#include "backtrace.h"
|
#include "backtrace.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NOMINMAX
|
||||||
|
#define NOMINMAX
|
||||||
|
#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
|
||||||
|
|
||||||
|
#if defined(_ARM_)
|
||||||
|
#define NTAPI
|
||||||
|
#else
|
||||||
|
#define NTAPI __stdcall
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This is a simplified (but binary compatible) version of what Microsoft
|
||||||
|
defines in their documentation. */
|
||||||
|
struct dll_notification_data
|
||||||
|
{
|
||||||
|
ULONG reserved;
|
||||||
|
/* The name as UNICODE_STRING struct. */
|
||||||
|
PVOID full_dll_name;
|
||||||
|
PVOID base_dll_name;
|
||||||
|
PVOID dll_base;
|
||||||
|
ULONG size_of_image;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LDR_DLL_NOTIFICATION_REASON_LOADED 1
|
||||||
|
|
||||||
|
typedef LONG NTSTATUS;
|
||||||
|
typedef VOID (CALLBACK *LDR_DLL_NOTIFICATION)(ULONG,
|
||||||
|
struct dll_notification_data*,
|
||||||
|
PVOID);
|
||||||
|
typedef NTSTATUS (NTAPI *LDR_REGISTER_FUNCTION)(ULONG,
|
||||||
|
LDR_DLL_NOTIFICATION, PVOID,
|
||||||
|
PVOID*);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Coff file header. */
|
/* Coff file header. */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -188,7 +240,7 @@ coff_nodebug (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
|||||||
backtrace_full_callback callback ATTRIBUTE_UNUSED,
|
backtrace_full_callback callback ATTRIBUTE_UNUSED,
|
||||||
backtrace_error_callback error_callback, void *data)
|
backtrace_error_callback error_callback, void *data)
|
||||||
{
|
{
|
||||||
error_callback (data, "no debug info in PE/COFF executable", -1);
|
error_callback (data, "no debug info in PE/COFF executable (make sure to compile with -g)", -1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,10 +382,11 @@ coff_is_function_symbol (const b_coff_internal_symbol *isym)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
coff_initialize_syminfo (struct backtrace_state *state,
|
coff_initialize_syminfo (struct backtrace_state *state,
|
||||||
uintptr_t base_address, int is_64,
|
struct libbacktrace_base_address base_address,
|
||||||
const b_coff_section_header *sects, size_t sects_num,
|
int is_64, const b_coff_section_header *sects,
|
||||||
const b_coff_external_symbol *syms, size_t syms_size,
|
size_t sects_num, const b_coff_external_symbol *syms,
|
||||||
const unsigned char *strtab, size_t strtab_size,
|
size_t syms_size, const unsigned char *strtab,
|
||||||
|
size_t strtab_size,
|
||||||
backtrace_error_callback error_callback,
|
backtrace_error_callback error_callback,
|
||||||
void *data, struct coff_syminfo_data *sdata)
|
void *data, struct coff_syminfo_data *sdata)
|
||||||
{
|
{
|
||||||
@@ -438,9 +491,10 @@ coff_initialize_syminfo (struct backtrace_state *state,
|
|||||||
secnum = coff_read2 (asym->section_number);
|
secnum = coff_read2 (asym->section_number);
|
||||||
|
|
||||||
coff_sym->name = name;
|
coff_sym->name = name;
|
||||||
coff_sym->address = (coff_read4 (asym->value)
|
coff_sym->address =
|
||||||
+ sects[secnum - 1].virtual_address
|
libbacktrace_add_base ((coff_read4 (asym->value)
|
||||||
+ base_address);
|
+ sects[secnum - 1].virtual_address),
|
||||||
|
base_address);
|
||||||
coff_sym++;
|
coff_sym++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -580,7 +634,8 @@ coff_syminfo (struct backtrace_state *state, uintptr_t addr,
|
|||||||
static int
|
static int
|
||||||
coff_add (struct backtrace_state *state, int descriptor,
|
coff_add (struct backtrace_state *state, int descriptor,
|
||||||
backtrace_error_callback error_callback, void *data,
|
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;
|
struct backtrace_view fhdr_view;
|
||||||
off_t fhdr_off;
|
off_t fhdr_off;
|
||||||
@@ -609,7 +664,8 @@ coff_add (struct backtrace_state *state, int descriptor,
|
|||||||
struct backtrace_view debug_view;
|
struct backtrace_view debug_view;
|
||||||
int debug_view_valid;
|
int debug_view_valid;
|
||||||
int is_64;
|
int is_64;
|
||||||
uintptr_t image_base;
|
struct libbacktrace_base_address image_base;
|
||||||
|
struct libbacktrace_base_address base_address;
|
||||||
struct dwarf_sections dwarf_sections;
|
struct dwarf_sections dwarf_sections;
|
||||||
|
|
||||||
*found_sym = 0;
|
*found_sym = 0;
|
||||||
@@ -648,7 +704,7 @@ coff_add (struct backtrace_state *state, int descriptor,
|
|||||||
magic_ok = memcmp (magic, "PE\0", 4) == 0;
|
magic_ok = memcmp (magic, "PE\0", 4) == 0;
|
||||||
fhdr_off += 4;
|
fhdr_off += 4;
|
||||||
|
|
||||||
memcpy (&fhdr, fhdr_view.data + 4, sizeof fhdr);
|
memcpy (&fhdr, (const unsigned char *) fhdr_view.data + 4, sizeof fhdr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -682,16 +738,17 @@ coff_add (struct backtrace_state *state, int descriptor,
|
|||||||
sects_view_valid = 1;
|
sects_view_valid = 1;
|
||||||
opt_hdr = (const b_coff_optional_header *) sects_view.data;
|
opt_hdr = (const b_coff_optional_header *) sects_view.data;
|
||||||
sects = (const b_coff_section_header *)
|
sects = (const b_coff_section_header *)
|
||||||
(sects_view.data + fhdr.size_of_optional_header);
|
((const unsigned char *) sects_view.data + fhdr.size_of_optional_header);
|
||||||
|
|
||||||
is_64 = 0;
|
is_64 = 0;
|
||||||
|
memset (&image_base, 0, sizeof image_base);
|
||||||
if (fhdr.size_of_optional_header > sizeof (*opt_hdr))
|
if (fhdr.size_of_optional_header > sizeof (*opt_hdr))
|
||||||
{
|
{
|
||||||
if (opt_hdr->magic == PE_MAGIC)
|
if (opt_hdr->magic == PE_MAGIC)
|
||||||
image_base = opt_hdr->u.pe.image_base;
|
image_base.m = opt_hdr->u.pe.image_base;
|
||||||
else if (opt_hdr->magic == PEP_MAGIC)
|
else if (opt_hdr->magic == PEP_MAGIC)
|
||||||
{
|
{
|
||||||
image_base = opt_hdr->u.pep.image_base;
|
image_base.m = opt_hdr->u.pep.image_base;
|
||||||
is_64 = 1;
|
is_64 = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -700,8 +757,6 @@ coff_add (struct backtrace_state *state, int descriptor,
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
image_base = 0;
|
|
||||||
|
|
||||||
/* Read the symbol table and the string table. */
|
/* Read the symbol table and the string table. */
|
||||||
|
|
||||||
@@ -726,7 +781,8 @@ coff_add (struct backtrace_state *state, int descriptor,
|
|||||||
goto fail;
|
goto fail;
|
||||||
syms_view_valid = 1;
|
syms_view_valid = 1;
|
||||||
|
|
||||||
str_size = coff_read4 (syms_view.data + syms_size);
|
str_size = coff_read4 ((const unsigned char *) syms_view.data
|
||||||
|
+ syms_size);
|
||||||
|
|
||||||
str_off = syms_off + syms_size;
|
str_off = syms_off + syms_size;
|
||||||
|
|
||||||
@@ -856,7 +912,12 @@ coff_add (struct backtrace_state *state, int descriptor,
|
|||||||
+ (sections[i].offset - min_offset));
|
+ (sections[i].offset - min_offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!backtrace_dwarf_add (state, /* base_address */ 0, &dwarf_sections,
|
memset (&base_address, 0, sizeof base_address);
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
base_address.m = module_handle - image_base.m;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!backtrace_dwarf_add (state, base_address, &dwarf_sections,
|
||||||
0, /* FIXME: is_bigendian */
|
0, /* FIXME: is_bigendian */
|
||||||
NULL, /* altlink */
|
NULL, /* altlink */
|
||||||
error_callback, data, fileline_fn,
|
error_callback, data, fileline_fn,
|
||||||
@@ -881,6 +942,53 @@ coff_add (struct backtrace_state *state, int descriptor,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
struct dll_notification_context
|
||||||
|
{
|
||||||
|
struct backtrace_state *state;
|
||||||
|
backtrace_error_callback error_callback;
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
static VOID CALLBACK
|
||||||
|
dll_notification (ULONG reason,
|
||||||
|
struct dll_notification_data *notification_data,
|
||||||
|
PVOID context)
|
||||||
|
{
|
||||||
|
char module_name[MAX_PATH];
|
||||||
|
int descriptor;
|
||||||
|
struct dll_notification_context* dll_context =
|
||||||
|
(struct dll_notification_context*) context;
|
||||||
|
struct backtrace_state *state = dll_context->state;
|
||||||
|
void *data = dll_context->data;
|
||||||
|
backtrace_error_callback error_callback = dll_context->data;
|
||||||
|
fileline fileline;
|
||||||
|
int found_sym;
|
||||||
|
int found_dwarf;
|
||||||
|
HMODULE module_handle;
|
||||||
|
|
||||||
|
if (reason != LDR_DLL_NOTIFICATION_REASON_LOADED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!GetModuleHandleExW ((GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
|
||||||
|
| GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT),
|
||||||
|
(wchar_t*) notification_data->dll_base,
|
||||||
|
&module_handle))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!GetModuleFileNameA ((HMODULE) module_handle, module_name, MAX_PATH - 1))
|
||||||
|
return;
|
||||||
|
|
||||||
|
descriptor = backtrace_open (module_name, error_callback, data, NULL);
|
||||||
|
|
||||||
|
if (descriptor < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
coff_add (state, descriptor, error_callback, data, &fileline, &found_sym,
|
||||||
|
&found_dwarf, (uintptr_t) module_handle);
|
||||||
|
}
|
||||||
|
#endif /* defined(HAVE_WINDOWS_H) */
|
||||||
|
|
||||||
/* Initialize the backtrace data we need from an ELF executable. At
|
/* Initialize the backtrace data we need from an ELF executable. At
|
||||||
the ELF level, all we need to do is find the debug info
|
the ELF level, all we need to do is find the debug info
|
||||||
sections. */
|
sections. */
|
||||||
@@ -895,12 +1003,92 @@ backtrace_initialize (struct backtrace_state *state,
|
|||||||
int found_sym;
|
int found_sym;
|
||||||
int found_dwarf;
|
int found_dwarf;
|
||||||
fileline coff_fileline_fn;
|
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
|
||||||
|
HMODULE nt_dll_handle;
|
||||||
|
|
||||||
|
module_handle = (uintptr_t) GetModuleHandle (NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
ret = coff_add (state, descriptor, error_callback, data,
|
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)
|
if (!ret)
|
||||||
return 0;
|
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
|
||||||
|
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
nt_dll_handle = GetModuleHandleW (L"ntdll.dll");
|
||||||
|
if (nt_dll_handle)
|
||||||
|
{
|
||||||
|
LDR_REGISTER_FUNCTION register_func;
|
||||||
|
const char register_name[] = "LdrRegisterDllNotification";
|
||||||
|
register_func = (void*) GetProcAddress (nt_dll_handle,
|
||||||
|
register_name);
|
||||||
|
|
||||||
|
if (register_func)
|
||||||
|
{
|
||||||
|
PVOID cookie;
|
||||||
|
struct dll_notification_context *context
|
||||||
|
= backtrace_alloc (state,
|
||||||
|
sizeof (struct dll_notification_context),
|
||||||
|
error_callback, data);
|
||||||
|
|
||||||
|
if (context)
|
||||||
|
{
|
||||||
|
context->state = state;
|
||||||
|
context->data = data;
|
||||||
|
context->error_callback = error_callback;
|
||||||
|
|
||||||
|
register_func (0, &dll_notification, context, &cookie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* defined(HAVE_WINDOWS_H) */
|
||||||
|
|
||||||
if (!state->threaded)
|
if (!state->threaded)
|
||||||
{
|
{
|
||||||
if (found_sym)
|
if (found_sym)
|
||||||
|
|||||||
2
thirdparty/libbacktrace/posix.c
vendored
2
thirdparty/libbacktrace/posix.c
vendored
@@ -1,5 +1,5 @@
|
|||||||
/* posix.c -- POSIX file I/O routines for the backtrace library.
|
/* posix.c -- POSIX file I/O routines for the backtrace library.
|
||||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
Copyright (C) 2012-2024 Free Software Foundation, Inc.
|
||||||
Written by Ian Lance Taylor, Google.
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
|||||||
59
thirdparty/libbacktrace/print.c
vendored
59
thirdparty/libbacktrace/print.c
vendored
@@ -1,5 +1,5 @@
|
|||||||
/* print.c -- Print the current backtrace.
|
/* print.c -- Print the current backtrace.
|
||||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
Copyright (C) 2012-2024 Free Software Foundation, Inc.
|
||||||
Written by Ian Lance Taylor, Google.
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -47,22 +47,6 @@ struct print_data
|
|||||||
FILE *f;
|
FILE *f;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Print one level of a backtrace. */
|
|
||||||
|
|
||||||
static int
|
|
||||||
print_callback (void *data, uintptr_t pc, const char *filename, int lineno,
|
|
||||||
const char *function)
|
|
||||||
{
|
|
||||||
struct print_data *pdata = (struct print_data *) data;
|
|
||||||
|
|
||||||
fprintf (pdata->f, "0x%lx %s\n\t%s:%d\n",
|
|
||||||
(unsigned long) pc,
|
|
||||||
function == NULL ? "???" : function,
|
|
||||||
filename == NULL ? "???" : filename,
|
|
||||||
lineno);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print errors to stderr. */
|
/* Print errors to stderr. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -78,6 +62,47 @@ error_callback (void *data, const char *msg, int errnum)
|
|||||||
fputc ('\n', stderr);
|
fputc ('\n', stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Print one level of a backtrace if we couldn't get a file or function name.
|
||||||
|
Use syminfo to try to get a symbol name. */
|
||||||
|
|
||||||
|
static void print_syminfo_callback (void *data, uintptr_t pc,
|
||||||
|
const char *symname, uintptr_t symval,
|
||||||
|
uintptr_t symsize ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
struct print_data *pdata = (struct print_data *) data;
|
||||||
|
|
||||||
|
if (symname == NULL)
|
||||||
|
fprintf (pdata->f, "0x%lx ???\n\t???:0\n", (unsigned long) pc);
|
||||||
|
else
|
||||||
|
fprintf (pdata->f, "0x%lx ???\n\t%s+0x%lx:0\n",
|
||||||
|
(unsigned long) pc,
|
||||||
|
symname,
|
||||||
|
(unsigned long) (pc - symval));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print one level of a backtrace. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
print_callback (void *data, uintptr_t pc, const char *filename, int lineno,
|
||||||
|
const char *function)
|
||||||
|
{
|
||||||
|
struct print_data *pdata = (struct print_data *) data;
|
||||||
|
|
||||||
|
if (function == NULL && filename == NULL)
|
||||||
|
{
|
||||||
|
backtrace_syminfo (pdata->state, pc, print_syminfo_callback,
|
||||||
|
error_callback, data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf (pdata->f, "0x%lx %s\n\t%s:%d\n",
|
||||||
|
(unsigned long) pc,
|
||||||
|
function == NULL ? "???" : function,
|
||||||
|
filename == NULL ? "???" : filename,
|
||||||
|
lineno);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Print a backtrace. */
|
/* Print a backtrace. */
|
||||||
|
|
||||||
void __attribute__((noinline))
|
void __attribute__((noinline))
|
||||||
|
|||||||
2
thirdparty/libbacktrace/read.c
vendored
2
thirdparty/libbacktrace/read.c
vendored
@@ -1,5 +1,5 @@
|
|||||||
/* read.c -- File views without mmap.
|
/* read.c -- File views without mmap.
|
||||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
Copyright (C) 2012-2024 Free Software Foundation, Inc.
|
||||||
Written by Ian Lance Taylor, Google.
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
|||||||
2
thirdparty/libbacktrace/simple.c
vendored
2
thirdparty/libbacktrace/simple.c
vendored
@@ -1,5 +1,5 @@
|
|||||||
/* simple.c -- The backtrace_simple function.
|
/* simple.c -- The backtrace_simple function.
|
||||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
Copyright (C) 2012-2024 Free Software Foundation, Inc.
|
||||||
Written by Ian Lance Taylor, Google.
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
|||||||
2
thirdparty/libbacktrace/sort.c
vendored
2
thirdparty/libbacktrace/sort.c
vendored
@@ -1,5 +1,5 @@
|
|||||||
/* sort.c -- Sort without allocating memory
|
/* sort.c -- Sort without allocating memory
|
||||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
Copyright (C) 2012-2024 Free Software Foundation, Inc.
|
||||||
Written by Ian Lance Taylor, Google.
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
|||||||
2
thirdparty/libbacktrace/state.c
vendored
2
thirdparty/libbacktrace/state.c
vendored
@@ -1,5 +1,5 @@
|
|||||||
/* state.c -- Create the backtrace state.
|
/* state.c -- Create the backtrace state.
|
||||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
Copyright (C) 2012-2024 Free Software Foundation, Inc.
|
||||||
Written by Ian Lance Taylor, Google.
|
Written by Ian Lance Taylor, Google.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
|||||||
Reference in New Issue
Block a user