aboutsummaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2021-10-27 08:47:25 -0700
committerIan Lance Taylor <iant@golang.org>2021-10-27 08:47:25 -0700
commita6d3012b274f38b20e2a57162106f625746af6c6 (patch)
tree09ff8b13eb8ff7594c27dc8812efbf696dc97484 /libgcc
parentcd2fd5facb5e1882d3f338ed456ae9536f7c0593 (diff)
parent99b1021d21e5812ed01221d8fca8e8a32488a934 (diff)
downloadgcc-a6d3012b274f38b20e2a57162106f625746af6c6.zip
gcc-a6d3012b274f38b20e2a57162106f625746af6c6.tar.gz
gcc-a6d3012b274f38b20e2a57162106f625746af6c6.tar.bz2
Merge from trunk revision 99b1021d21e5812ed01221d8fca8e8a32488a934.
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog32
-rw-r--r--libgcc/config/or1k/sfp-machine.h2
-rw-r--r--libgcc/config/rs6000/linux-unwind.h102
-rw-r--r--libgcc/libgcov-driver.c8
-rw-r--r--libgcc/libgcov-util.c3
-rw-r--r--libgcc/libgcov.h1
-rw-r--r--libgcc/unwind.inc14
7 files changed, 143 insertions, 19 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 5ecd436..19ce607 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,35 @@
+2021-10-22 Stafford Horne <shorne@gmail.com>
+
+ * config/or1k/sfp-machine.h (_FP_TININESS_AFTER_ROUNDING):
+ Change to 0.
+
+2021-10-14 Raphael Moreira Zinsly <rzinsly@linux.ibm.com>
+
+ * config/rs6000/linux-unwind.h (struct rt_sigframe): Move it to
+ outside of get_regs() in order to use it in another function, this
+ is done twice: for __powerpc64__ and for !__powerpc64__.
+ (struct trace_arg): New struct.
+ (struct layout): New struct.
+ (ppc_backchain_fallback): New function.
+ * unwind.inc (_Unwind_Backtrace): Look for _URC_NORMAL_STOP code
+ state and call MD_BACKCHAIN_FALLBACK.
+
+2021-10-13 Martin Liska <mliska@suse.cz>
+
+ PR gcov-profile/90364
+ * libgcov-driver.c (merge_one_data): Skip timestamp and verify
+ checksums.
+ (write_one_data): Write also checksum.
+ * libgcov-util.c (read_gcda_file): Read also checksum field.
+ * libgcov.h (struct gcov_info): Add new field.
+
+2021-10-08 Ian Lance Taylor <iant@golang.org>
+
+ * config/i386/morestack.S: Use .init_array for constructor if
+ available.
+ * config/rs6000/morestack.S: Likewise.
+ * config/s390/morestack.S: Likewise.
+
2021-10-03 Patrick McGehearty <patrick.mcgehearty@oracle.com>
PR target/101104
diff --git a/libgcc/config/or1k/sfp-machine.h b/libgcc/config/or1k/sfp-machine.h
index eebe5b0..162c6bc 100644
--- a/libgcc/config/or1k/sfp-machine.h
+++ b/libgcc/config/or1k/sfp-machine.h
@@ -85,7 +85,7 @@ do { \
#define __BYTE_ORDER __BIG_ENDIAN
-#define _FP_TININESS_AFTER_ROUNDING 1
+#define _FP_TININESS_AFTER_ROUNDING 0
/* Define ALIASNAME as a strong alias for NAME. */
# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
diff --git a/libgcc/config/rs6000/linux-unwind.h b/libgcc/config/rs6000/linux-unwind.h
index acdc948..8deccc1d 100644
--- a/libgcc/config/rs6000/linux-unwind.h
+++ b/libgcc/config/rs6000/linux-unwind.h
@@ -94,6 +94,15 @@ struct gcc_ucontext
enum { SIGNAL_FRAMESIZE = 128 };
+struct rt_sigframe {
+ char gap[SIGNAL_FRAMESIZE];
+ struct gcc_ucontext uc;
+ unsigned long pad[2];
+ int tramp[6];
+ void *pinfo;
+ struct gcc_ucontext *puc;
+};
+
/* If PC is at a sigreturn trampoline, return a pointer to the
regs. Otherwise return NULL. */
@@ -136,14 +145,7 @@ get_regs (struct _Unwind_Context *context)
#endif
{
/* This works for 2.4.21 and later kernels. */
- struct rt_sigframe {
- char gap[SIGNAL_FRAMESIZE];
- struct gcc_ucontext uc;
- unsigned long pad[2];
- int tramp[6];
- void *pinfo;
- struct gcc_ucontext *puc;
- } *frame = (struct rt_sigframe *) context->cfa;
+ struct rt_sigframe *frame = (struct rt_sigframe *) context->cfa;
return frame->uc.regs;
}
}
@@ -154,6 +156,12 @@ get_regs (struct _Unwind_Context *context)
enum { SIGNAL_FRAMESIZE = 64 };
+struct rt_sigframe {
+ char gap[SIGNAL_FRAMESIZE + 16];
+ char siginfo[128];
+ struct gcc_ucontext uc;
+};
+
static struct gcc_regs *
get_regs (struct _Unwind_Context *context)
{
@@ -176,11 +184,7 @@ get_regs (struct _Unwind_Context *context)
}
else if (pc[0] == 0x38006666 || pc[0] == 0x380000AC)
{
- struct rt_sigframe {
- char gap[SIGNAL_FRAMESIZE + 16];
- char siginfo[128];
- struct gcc_ucontext uc;
- } *frame = (struct rt_sigframe *) context->cfa;
+ struct rt_sigframe *frame = (struct rt_sigframe *) context->cfa;
return frame->uc.regs;
}
return NULL;
@@ -203,7 +207,7 @@ ppc_fallback_frame_state (struct _Unwind_Context *context,
int i;
if (regs == NULL)
- return _URC_END_OF_STACK;
+ return _URC_NORMAL_STOP;
new_cfa = regs->gpr[__LIBGCC_STACK_POINTER_REGNUM__];
fs->regs.cfa_how = CFA_REG_OFFSET;
@@ -352,3 +356,73 @@ frob_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs ATT
}
#endif
}
+
+#define MD_BACKCHAIN_FALLBACK ppc_backchain_fallback
+
+struct trace_arg
+{
+ /* Stores the list of addresses. */
+ void **array;
+ struct unwind_link *unwind_link;
+ _Unwind_Word cfa;
+ /* Number of addresses currently stored. */
+ int count;
+ /* Maximum number of addresses. */
+ int size;
+};
+
+/* This is the stack layout we see with every stack frame.
+ Note that every routine is required by the ABI to lay out the stack
+ like this.
+
+ +----------------+ +-----------------+
+ %r1 -> | previous frame--------> | previous frame--->... --> NULL
+ | | | |
+ | cr save | | cr save |
+ | | | |
+ | (unused) | | lr save |
+ +----------------+ +-----------------+
+
+ The CR save is only present on 64-bit ABIs.
+*/
+struct frame_layout
+{
+ struct frame_layout *backchain;
+#ifdef __powerpc64__
+ long int cr_save;
+#endif
+ void *lr_save;
+};
+
+
+void ppc_backchain_fallback (struct _Unwind_Context *context, void *a)
+{
+ struct frame_layout *current;
+ struct trace_arg *arg = a;
+ int count;
+
+ /* Get the last address computed and start with the next. */
+ current = context->cfa;
+ current = current->backchain;
+
+ for (count = arg->count; current != NULL; current = current->backchain)
+ {
+ arg->array[count] = current->lr_save;
+
+ /* Check if the symbol is the signal trampoline and get the interrupted
+ symbol address from the trampoline saved area. */
+ context->ra = current->lr_save;
+ if (current->lr_save && get_regs (context))
+ {
+ struct rt_sigframe *sigframe = (struct rt_sigframe *) current;
+ if (count + 1 == arg->size)
+ break;
+ arg->array[++count] = (void *) sigframe->uc.rsave.nip;
+ current = (void *) sigframe->uc.rsave.gpr[1];
+ }
+ if (count++ >= arg->size)
+ break;
+ }
+
+ arg->count = count-1;
+}
diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
index 087f71e..7aa97bb 100644
--- a/libgcc/libgcov-driver.c
+++ b/libgcc/libgcov-driver.c
@@ -260,12 +260,15 @@ merge_one_data (const char *filename,
if (!gcov_version (gi_ptr, length, filename))
return -1;
+ /* Skip timestamp. */
+ gcov_read_unsigned ();
+
length = gcov_read_unsigned ();
- if (length != gi_ptr->stamp)
+ if (length != gi_ptr->checksum)
{
/* Read from a different compilation. Overwrite the file. */
gcov_error (GCOV_PROF_PREFIX "overwriting an existing profile data "
- "with a different timestamp\n", filename);
+ "with a different checksum\n", filename);
return 0;
}
@@ -495,6 +498,7 @@ write_one_data (const struct gcov_info *gi_ptr,
dump_unsigned (GCOV_DATA_MAGIC, dump_fn, arg);
dump_unsigned (GCOV_VERSION, dump_fn, arg);
dump_unsigned (gi_ptr->stamp, dump_fn, arg);
+ dump_unsigned (gi_ptr->checksum, dump_fn, arg);
#ifdef NEED_L_GCOV
/* Generate whole program statistics. */
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index bc7416d..766ca35 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -310,6 +310,9 @@ read_gcda_file (const char *filename)
/* Read stamp. */
obj_info->stamp = gcov_read_unsigned ();
+ /* Read checksum. */
+ obj_info->checksum = gcov_read_unsigned ();
+
while (1)
{
gcov_position_t base;
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index f6354a7..2a365c9 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -230,6 +230,7 @@ struct gcov_info
struct gcov_info *next; /* link to next, used by libgcov */
gcov_unsigned_t stamp; /* uniquifying time stamp */
+ gcov_unsigned_t checksum; /* unique object checksum */
const char *filename; /* output file name */
gcov_merge_fn merge[GCOV_COUNTERS]; /* merge functions (null for
diff --git a/libgcc/unwind.inc b/libgcc/unwind.inc
index aa48d10..456a5ee 100644
--- a/libgcc/unwind.inc
+++ b/libgcc/unwind.inc
@@ -300,14 +300,24 @@ _Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument)
/* Set up fs to describe the FDE for the caller of context. */
code = uw_frame_state_for (&context, &fs);
- if (code != _URC_NO_REASON && code != _URC_END_OF_STACK)
+ if (code != _URC_NO_REASON && code != _URC_END_OF_STACK
+ && code != _URC_NORMAL_STOP)
return _URC_FATAL_PHASE1_ERROR;
/* Call trace function. */
if ((*trace) (&context, trace_argument) != _URC_NO_REASON)
return _URC_FATAL_PHASE1_ERROR;
- /* We're done at end of stack. */
+#ifdef MD_BACKCHAIN_FALLBACK
+ /* Do a backchain if there is no DWARF data. */
+ if (code == _URC_NORMAL_STOP)
+ {
+ MD_BACKCHAIN_FALLBACK(&context, trace_argument);
+ break;
+ }
+#endif
+
+ /* We're done at end of stack. */
if (code == _URC_END_OF_STACK)
break;