[AArch64] Fix libc internal asm profiling code

Message ID 56991443.4080700@arm.com
State New, archived
Headers

Commit Message

Szabolcs Nagy Jan. 15, 2016, 3:46 p.m. UTC
  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.

2016-01-15  Szabolcs Nagy  <szabolcs.nagy@arm.com>

     * sysdeps/aarch64/Makefile (CFLAGS-mcount.c): Add -mgeneral-regs-only.
     * sysdeps/aarch64/sysdep.h (CALL_MCOUNT): Save argument registers.
  

Comments

Joseph Myers Jan. 15, 2016, 10:25 p.m. UTC | #1
If this fixes bug 18707, then include [BZ #18707] in the ChangeLog entry 
and close the bug as fixed with the appropriate milestone set on commit.
  
Szabolcs Nagy July 8, 2016, 4:06 p.m. UTC | #2
On 15/01/16 15:46, Szabolcs Nagy wrote:
> 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.
> 
> 2016-01-15  Szabolcs Nagy  <szabolcs.nagy@arm.com>
> 
>     * sysdeps/aarch64/Makefile (CFLAGS-mcount.c): Add -mgeneral-regs-only.
>     * sysdeps/aarch64/sysdep.h (CALL_MCOUNT): Save argument registers.

ping.

with bz in changelog:

2016-07-08  Szabolcs Nagy  <szabolcs.nagy@arm.com>

	[BZ #18707]
	* sysdeps/aarch64/Makefile (CFLAGS-mcount.c): Add -mgeneral-regs-only.
	* sysdeps/aarch64/sysdep.h (CALL_MCOUNT): Save argument registers.
  
Marcus Shawcroft July 11, 2016, 8:23 a.m. UTC | #3
> On 8 Jul 2016, at 17:06, Szabolcs Nagy <Szabolcs.Nagy@arm.com> wrote:
> 
> 2016-07-08  Szabolcs Nagy  <szabolcs.nagy@arm.com>
> 
> 	[BZ #18707]
> 	* sysdeps/aarch64/Makefile (CFLAGS-mcount.c): Add -mgeneral-regs-only.
> 	* sysdeps/aarch64/sysdep.h (CALL_MCOUNT): Save argument registers.

OK /Marcus
  

Patch

diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile
index 0632355..562c137 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 af1af70..d1f8c22 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