aboutsummaryrefslogtreecommitdiff
path: root/libbacktrace/dwarf.c
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2024-07-15 17:27:18 -0700
committerIan Lance Taylor <iant@golang.org>2024-07-15 17:28:28 -0700
commitc6803cdaba7a7bf933e52cd36f901430253cc2b0 (patch)
tree37c73933cd56cf4f5f4067276820f4b9bb2cb34d /libbacktrace/dwarf.c
parent7d27018bd56b513b16641948a3bdbb7d7e83218e (diff)
downloadgcc-c6803cdaba7a7bf933e52cd36f901430253cc2b0.zip
gcc-c6803cdaba7a7bf933e52cd36f901430253cc2b0.tar.gz
gcc-c6803cdaba7a7bf933e52cd36f901430253cc2b0.tar.bz2
libbacktrace: support FDPIC
Based on patch by Max Filippov. * internal.h: If FDPIC, #include <link.h> and/or <sys/link.h>. (libbacktrace_using_fdpic): Define. (struct libbacktrace_base_address): Define. (libbacktrace_add_base): Define. (backtrace_dwarf_add): Change base_address to struct libbacktrace_base_address. * dwarf.c (struct dwarf_data): Change base_address to struct libbacktrace_base_address. (add_ranges, find_address_ranges, build_ddress_map): Likewise. (build_dwarf_data, build_dwarf_add): Likewise. (add_low_high_range): Change base_address to struct libbacktrace_base_address. Use libbacktrace_add_base. (add_ranges_from_ranges, add_ranges_from_rnglists): Likewise. (add_line): Use libbacktrace_add_base. * elf.c (elf_initialize_syminfo): Change base_address to struct libbacktrace_base_address. Use libbacktrace_add_base. (elf_add): Change base_address to struct libbacktrace_base_address. (phdr_callback): Likewise. Initialize base_address.m. (backtrace_initialize): If using FDPIC, don't call elf_add with main executable; always use dl_iterate_phdr. * macho.c (macho_add_symtab): Change base_address to struct libbacktrace_base_address. Use libbacktrace_add_base. (macho_syminfo): Change base_address to struct libbacktrace_base_address. (macho_add_fat, macho_add_dsym, macho_add): Likewise. (backtrace_initialize): Likewise. Initialize base_address.m. * pecoff.c (coff_initialize_syminfo): Change base_address to struct libbacktrace_base_address. Use libbacktrace_add_base. (coff_add): Change base_address to struct libbacktrace_base_address. Initialize base_address.m.
Diffstat (limited to 'libbacktrace/dwarf.c')
-rw-r--r--libbacktrace/dwarf.c63
1 files changed, 35 insertions, 28 deletions
diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index cc36a0a..96ffc4c 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -388,8 +388,8 @@ struct dwarf_data
struct dwarf_data *next;
/* The data for .gnu_debugaltlink. */
struct dwarf_data *altlink;
- /* The base address for this file. */
- uintptr_t base_address;
+ /* The base address mapping for this file. */
+ struct libbacktrace_base_address base_address;
/* A sorted list of address ranges. */
struct unit_addrs *addrs;
/* Number of address ranges in list. */
@@ -1610,8 +1610,9 @@ update_pcrange (const struct attr* attr, const struct attr_val* val,
static int
add_low_high_range (struct backtrace_state *state,
const struct dwarf_sections *dwarf_sections,
- uintptr_t base_address, int is_bigendian,
- struct unit *u, const struct pcrange *pcrange,
+ struct libbacktrace_base_address base_address,
+ int is_bigendian, struct unit *u,
+ const struct pcrange *pcrange,
int (*add_range) (struct backtrace_state *state,
void *rdata, uintptr_t lowpc,
uintptr_t highpc,
@@ -1646,8 +1647,8 @@ add_low_high_range (struct backtrace_state *state,
/* Add in the base address of the module when recording PC values,
so that we can look up the PC directly. */
- lowpc += base_address;
- highpc += base_address;
+ lowpc = libbacktrace_add_base (lowpc, base_address);
+ highpc = libbacktrace_add_base (highpc, base_address);
return add_range (state, rdata, lowpc, highpc, error_callback, data, vec);
}
@@ -1659,7 +1660,7 @@ static int
add_ranges_from_ranges (
struct backtrace_state *state,
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, uintptr_t base,
const struct pcrange *pcrange,
int (*add_range) (struct backtrace_state *state, void *rdata,
@@ -1705,10 +1706,11 @@ add_ranges_from_ranges (
base = (uintptr_t) high;
else
{
- if (!add_range (state, rdata,
- (uintptr_t) low + base + base_address,
- (uintptr_t) high + base + base_address,
- error_callback, data, vec))
+ uintptr_t rl, rh;
+
+ rl = libbacktrace_add_base ((uintptr_t) low + base, base_address);
+ rh = libbacktrace_add_base ((uintptr_t) high + base, base_address);
+ if (!add_range (state, rdata, rl, rh, error_callback, data, vec))
return 0;
}
}
@@ -1726,7 +1728,7 @@ static int
add_ranges_from_rnglists (
struct backtrace_state *state,
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, uintptr_t base,
const struct pcrange *pcrange,
int (*add_range) (struct backtrace_state *state, void *rdata,
@@ -1809,9 +1811,10 @@ add_ranges_from_rnglists (
u->addrsize, is_bigendian, index,
error_callback, data, &high))
return 0;
- if (!add_range (state, rdata, low + base_address,
- high + base_address, error_callback, data,
- vec))
+ if (!add_range (state, rdata,
+ libbacktrace_add_base (low, base_address),
+ libbacktrace_add_base (high, base_address),
+ error_callback, data, vec))
return 0;
}
break;
@@ -1828,7 +1831,7 @@ add_ranges_from_rnglists (
error_callback, data, &low))
return 0;
length = read_uleb128 (&rnglists_buf);
- low += base_address;
+ low = libbacktrace_add_base (low, base_address);
if (!add_range (state, rdata, low, low + length,
error_callback, data, vec))
return 0;
@@ -1842,8 +1845,9 @@ add_ranges_from_rnglists (
low = read_uleb128 (&rnglists_buf);
high = read_uleb128 (&rnglists_buf);
- if (!add_range (state, rdata, low + base + base_address,
- high + base + base_address,
+ if (!add_range (state, rdata,
+ libbacktrace_add_base (low + base, base_address),
+ libbacktrace_add_base (high + base, base_address),
error_callback, data, vec))
return 0;
}
@@ -1860,9 +1864,10 @@ add_ranges_from_rnglists (
low = (uintptr_t) read_address (&rnglists_buf, u->addrsize);
high = (uintptr_t) read_address (&rnglists_buf, u->addrsize);
- if (!add_range (state, rdata, low + base_address,
- high + base_address, error_callback, data,
- vec))
+ if (!add_range (state, rdata,
+ libbacktrace_add_base (low, base_address),
+ libbacktrace_add_base (high, base_address),
+ error_callback, data, vec))
return 0;
}
break;
@@ -1874,7 +1879,7 @@ add_ranges_from_rnglists (
low = (uintptr_t) read_address (&rnglists_buf, u->addrsize);
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,
error_callback, data, vec))
return 0;
@@ -1902,7 +1907,7 @@ add_ranges_from_rnglists (
static int
add_ranges (struct backtrace_state *state,
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, uintptr_t base, const struct pcrange *pcrange,
int (*add_range) (struct backtrace_state *state, void *rdata,
uintptr_t lowpc, uintptr_t highpc,
@@ -1938,7 +1943,8 @@ add_ranges (struct backtrace_state *state,
read, 0 if there is some error. */
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,
const struct dwarf_sections *dwarf_sections,
int is_bigendian, struct dwarf_data *altlink,
@@ -2093,7 +2099,8 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
on success, 0 on failure. */
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,
int is_bigendian, struct dwarf_data *altlink,
backtrace_error_callback error_callback, void *data,
@@ -2312,7 +2319,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
directly. */
- ln->pc = pc + ddata->base_address;
+ ln->pc = libbacktrace_add_base (pc, ddata->base_address);
ln->filename = filename;
ln->lineno = lineno;
@@ -3951,7 +3958,7 @@ dwarf_fileline (struct backtrace_state *state, uintptr_t pc,
static struct dwarf_data *
build_dwarf_data (struct backtrace_state *state,
- uintptr_t base_address,
+ struct libbacktrace_base_address base_address,
const struct dwarf_sections *dwarf_sections,
int is_bigendian,
struct dwarf_data *altlink,
@@ -4009,7 +4016,7 @@ build_dwarf_data (struct backtrace_state *state,
int
backtrace_dwarf_add (struct backtrace_state *state,
- uintptr_t base_address,
+ struct libbacktrace_base_address base_address,
const struct dwarf_sections *dwarf_sections,
int is_bigendian,
struct dwarf_data *fileline_altlink,