From efbe665c3a2d344b0d64456cf29499ba53c2965a Mon Sep 17 00:00:00 2001 From: Szabolcs Nagy Date: Mon, 11 Jul 2016 09:46:08 +0100 Subject: [PATCH] [AArch64] Fix libc internal asm profiling code When glibc is built with --enable-profile, the ENTRY of asm functions includes CALL_MCOUNT for profiling. (matters for binaries static linked against libc_p.a.) CALL_MCOUNT did not save/restore argument registers around the _mcount call so it clobbered them. (it is enough to only save/restore the arguments passed to a given asm function, but that would be too many asm changes so it is simpler to always save all argument registers in this macro.) float args are not saved: mcount does not clobber the float regs and currently no asm function takes float arguments anyway. [BZ #18707] * sysdeps/aarch64/Makefile (CFLAGS-mcount.c): Add -mgeneral-regs-only. * sysdeps/aarch64/sysdep.h (CALL_MCOUNT): Save argument registers. --- ChangeLog | 6 ++++++ sysdeps/aarch64/Makefile | 4 ++++ sysdeps/aarch64/sysdep.h | 33 +++++++++++++++++++++++++++++++-- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 222e4d326d..8e230e9780 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2016-07-11 Szabolcs Nagy + + [BZ #18707] + * sysdeps/aarch64/Makefile (CFLAGS-mcount.c): Add -mgeneral-regs-only. + * sysdeps/aarch64/sysdep.h (CALL_MCOUNT): Save argument registers. + 2016-07-08 Adhemerval Zanella * sysdeps/unix/sysv/linux/sysdep.h diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile index 06323550e9..562c1373ae 100644 --- a/sysdeps/aarch64/Makefile +++ b/sysdeps/aarch64/Makefile @@ -12,3 +12,7 @@ endif ifeq ($(subdir),csu) gen-as-const-headers += tlsdesc.sym endif + +ifeq ($(subdir),gmon) +CFLAGS-mcount.c += -mgeneral-regs-only +endif diff --git a/sysdeps/aarch64/sysdep.h b/sysdeps/aarch64/sysdep.h index 6b728ec651..e0457593fc 100644 --- a/sysdeps/aarch64/sysdep.h +++ b/sysdeps/aarch64/sysdep.h @@ -66,9 +66,38 @@ /* If compiled for profiling, call `mcount' at the start of each function. */ #ifdef PROF # define CALL_MCOUNT \ - str x30, [sp, #-16]!; \ + str x30, [sp, #-80]!; \ + cfi_adjust_cfa_offset (80); \ + cfi_rel_offset (x30, 0); \ + stp x0, x1, [sp, #16]; \ + cfi_rel_offset (x0, 16); \ + cfi_rel_offset (x1, 24); \ + stp x2, x3, [sp, #32]; \ + cfi_rel_offset (x2, 32); \ + cfi_rel_offset (x3, 40); \ + stp x4, x5, [sp, #48]; \ + cfi_rel_offset (x4, 48); \ + cfi_rel_offset (x5, 56); \ + stp x6, x7, [sp, #64]; \ + cfi_rel_offset (x6, 64); \ + cfi_rel_offset (x7, 72); \ + mov x0, x30; \ bl mcount; \ - ldr x30, [sp], #16 ; + ldp x0, x1, [sp, #16]; \ + cfi_restore (x0); \ + cfi_restore (x1); \ + ldp x2, x3, [sp, #32]; \ + cfi_restore (x2); \ + cfi_restore (x3); \ + ldp x4, x5, [sp, #48]; \ + cfi_restore (x4); \ + cfi_restore (x5); \ + ldp x6, x7, [sp, #64]; \ + cfi_restore (x6); \ + cfi_restore (x7); \ + ldr x30, [sp], #80; \ + cfi_adjust_cfa_offset (-80); \ + cfi_restore (x30); #else # define CALL_MCOUNT /* Do nothing. */ #endif