summaryrefslogtreecommitdiff
path: root/libbacktrace
diff options
context:
space:
mode:
Diffstat (limited to 'libbacktrace')
-rw-r--r--libbacktrace/ChangeLog20
-rwxr-xr-xlibbacktrace/configure17
-rw-r--r--libbacktrace/elf.c65
3 files changed, 98 insertions, 4 deletions
diff --git a/libbacktrace/ChangeLog b/libbacktrace/ChangeLog
index 9ebce200e37..64733a82ca2 100644
--- a/libbacktrace/ChangeLog
+++ b/libbacktrace/ChangeLog
@@ -1,3 +1,23 @@
+2018-02-14 Igor Tsimbalist <igor.v.tsimbalist@intel.com>
+
+ PR target/84148
+ * configure: Regenerate.
+
+2018-02-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR other/82368
+ * elf.c (SHT_PROGBITS): Undefine and define.
+
+2018-02-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR other/82368
+ * elf.c (EM_PPC64, EF_PPC64_ABI): Undefine and define.
+ (struct elf_ppc64_opd_data): New type.
+ (elf_initialize_syminfo): Add opd argument, handle symbols
+ pointing into the PowerPC64 ELFv1 .opd section.
+ (elf_add): Read .opd section on PowerPC64 ELFv1, pass pointer
+ to structure with .opd data to elf_initialize_syminfo.
+
2018-01-31 Ian Lance Taylor <iant@golang.org>
* elf.c (elf_add): Close descriptor if we use a debugfile.
diff --git a/libbacktrace/configure b/libbacktrace/configure
index 8943b0ca7fd..77c6fe34d1e 100755
--- a/libbacktrace/configure
+++ b/libbacktrace/configure
@@ -11802,18 +11802,28 @@ else
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CET support" >&5
+$as_echo_n "checking for CET support... " >&6; }
+
case "$host" in
i[34567]86-*-linux* | x86_64-*-linux*)
case "$enable_cet" in
default)
- # Check if assembler supports CET.
+ # Check if target supports multi-byte NOPs
+ # and if assembler supports CET insn.
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
+
+#if !defined(__SSE2__)
+#error target does not support multi-byte NOPs
+#else
asm ("setssbsy");
+#endif
+
;
return 0;
}
@@ -11853,6 +11863,11 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
esac
if test x$enable_cet = xyes; then
CET_FLAGS="-fcf-protection -mcet"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
EXTRA_FLAGS="$EXTRA_FLAGS $CET_FLAGS"
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index 3ee1dbeaf79..19da5a97b23 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -165,9 +165,12 @@ dl_iterate_phdr (int (*callback) (struct dl_phdr_info *,
#undef ELFDATA2MSB
#undef EV_CURRENT
#undef ET_DYN
+#undef EM_PPC64
+#undef EF_PPC64_ABI
#undef SHN_LORESERVE
#undef SHN_XINDEX
#undef SHN_UNDEF
+#undef SHT_PROGBITS
#undef SHT_SYMTAB
#undef SHT_STRTAB
#undef SHT_DYNSYM
@@ -245,6 +248,9 @@ typedef struct {
#define ET_DYN 3
+#define EM_PPC64 21
+#define EF_PPC64_ABI 3
+
typedef struct {
b_elf_word sh_name; /* Section name, index in string tbl */
b_elf_word sh_type; /* Type of section */
@@ -262,6 +268,7 @@ typedef struct {
#define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */
#define SHN_XINDEX 0xFFFF /* Section index is held elsewhere */
+#define SHT_PROGBITS 1
#define SHT_SYMTAB 2
#define SHT_STRTAB 3
#define SHT_DYNSYM 11
@@ -405,6 +412,20 @@ struct elf_syminfo_data
size_t count;
};
+/* Information about PowerPC64 ELFv1 .opd section. */
+
+struct elf_ppc64_opd_data
+{
+ /* Address of the .opd section. */
+ b_elf_addr addr;
+ /* Section data. */
+ const char *data;
+ /* Size of the .opd section. */
+ size_t size;
+ /* Corresponding section view. */
+ struct backtrace_view view;
+};
+
/* Compute the CRC-32 of BUF/LEN. This uses the CRC used for
.gnu_debuglink files. */
@@ -569,7 +590,8 @@ elf_initialize_syminfo (struct backtrace_state *state,
const unsigned char *symtab_data, size_t symtab_size,
const unsigned char *strtab, size_t strtab_size,
backtrace_error_callback error_callback,
- void *data, struct elf_syminfo_data *sdata)
+ void *data, struct elf_syminfo_data *sdata,
+ struct elf_ppc64_opd_data *opd)
{
size_t sym_count;
const b_elf_sym *sym;
@@ -620,7 +642,17 @@ elf_initialize_syminfo (struct backtrace_state *state,
return 0;
}
elf_symbols[j].name = (const char *) strtab + sym->st_name;
- elf_symbols[j].address = sym->st_value + base_address;
+ /* Special case PowerPC64 ELFv1 symbols in .opd section, if the symbol
+ is a function descriptor, read the actual code address from the
+ descriptor. */
+ if (opd
+ && sym->st_value >= opd->addr
+ && sym->st_value < opd->addr + opd->size)
+ elf_symbols[j].address
+ = *(const b_elf_addr *) (opd->data + (sym->st_value - opd->addr));
+ else
+ elf_symbols[j].address = sym->st_value;
+ elf_symbols[j].address += base_address;
elf_symbols[j].size = sym->st_size;
++j;
}
@@ -2637,6 +2669,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
int debug_view_valid;
unsigned int using_debug_view;
uint16_t *zdebug_table;
+ struct elf_ppc64_opd_data opd_data, *opd;
if (!debuginfo)
{
@@ -2655,6 +2688,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
debuglink_name = NULL;
debuglink_crc = 0;
debug_view_valid = 0;
+ opd = NULL;
if (!backtrace_get_view (state, descriptor, 0, sizeof ehdr, error_callback,
data, &ehdr_view))
@@ -2857,6 +2891,23 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
debuglink_crc = *(const uint32_t*)(debuglink_data + crc_offset);
}
}
+
+ /* Read the .opd section on PowerPC64 ELFv1. */
+ if (ehdr.e_machine == EM_PPC64
+ && (ehdr.e_flags & EF_PPC64_ABI) < 2
+ && shdr->sh_type == SHT_PROGBITS
+ && strcmp (name, ".opd") == 0)
+ {
+ if (!backtrace_get_view (state, descriptor, shdr->sh_offset,
+ shdr->sh_size, error_callback, data,
+ &opd_data.view))
+ goto fail;
+
+ opd = &opd_data;
+ opd->addr = shdr->sh_addr;
+ opd->data = (const char *) opd_data.view.data;
+ opd->size = shdr->sh_size;
+ }
}
if (symtab_shndx == 0)
@@ -2898,7 +2949,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
if (!elf_initialize_syminfo (state, base_address,
symtab_view.data, symtab_shdr->sh_size,
strtab_view.data, strtab_shdr->sh_size,
- error_callback, data, sdata))
+ error_callback, data, sdata, opd))
{
backtrace_free (state, sdata, sizeof *sdata, error_callback, data);
goto fail;
@@ -2951,6 +3002,12 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
buildid_view_valid = 0;
}
+ if (opd)
+ {
+ backtrace_release_view (state, &opd->view, error_callback, data);
+ opd = NULL;
+ }
+
if (debuglink_name != NULL)
{
int d;
@@ -3139,6 +3196,8 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
backtrace_release_view (state, &buildid_view, error_callback, data);
if (debug_view_valid)
backtrace_release_view (state, &debug_view, error_callback, data);
+ if (opd)
+ backtrace_release_view (state, &opd->view, error_callback, data);
if (descriptor != -1)
backtrace_close (descriptor, error_callback, data);
return 0;