Module Name: src Committed By: rin Date: Fri May 6 04:49:13 UTC 2022
Modified Files: src/lib/libc/gmon: gmon.c Log Message: PR lib/56395 PR toolchain/56771 Fix profiling on CPUs that do not support unaligned memory access; Allocate objects (referenced from struct gmonparam) with proper alignments. For monstartup(), objects are allocated on heap. Break is not guaranteed to be aligned at all, unlike stack pointer. For _m_gmon_alloc(), objects are allocated on anonymous memory. p->tos is not aligned properly in general. This fixes quasi-random crashes for *_profile tests, at least on SH-4 and PowerPC 403 [1]. Also, no regression is observed for others as far as I can see. This change does not cause any ABI breakage, as long as application uses proper pointers; use p->tos instead of evil pointer arithmetic like (struct tostruct *)((char *)p->froms + p->fromssize) [2]. [1] Timeout should be increased for some tests. "pic" variants still fail as expected. Dynamically-linked binaries also crash in rtld for SH-4, but this seems different problem... [2] This example did not work even before, since the order of froms[] and tos[] is reversed depending on which of monstartup() or _m_gmon_alloc() is used for allocation. To generate a diff of this commit: cvs rdiff -u -r1.36 -r1.37 src/lib/libc/gmon/gmon.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libc/gmon/gmon.c diff -u src/lib/libc/gmon/gmon.c:1.36 src/lib/libc/gmon/gmon.c:1.37 --- src/lib/libc/gmon/gmon.c:1.36 Sat Jul 3 14:08:55 2021 +++ src/lib/libc/gmon/gmon.c Fri May 6 04:49:13 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: gmon.c,v 1.36 2021/07/03 14:08:55 christos Exp $ */ +/* $NetBSD: gmon.c,v 1.37 2022/05/06 04:49:13 rin Exp $ */ /* * Copyright (c) 2003, 2004 Wasabi Systems, Inc. @@ -69,7 +69,7 @@ #if 0 static char sccsid[] = "@(#)gmon.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: gmon.c,v 1.36 2021/07/03 14:08:55 christos Exp $"); +__RCSID("$NetBSD: gmon.c,v 1.37 2022/05/06 04:49:13 rin Exp $"); #endif #endif @@ -141,21 +141,25 @@ monstartup(u_long lowpc, u_long highpc) p->tolimit = MAXARCS; p->tossize = p->tolimit * sizeof(struct tostruct); - cp = sbrk((intptr_t)(p->kcountsize + p->fromssize + p->tossize)); - if (cp == (char *)-1) { + cp = sbrk((intptr_t)0); + +#define GMON_ALLOC(buf, ptr, size) \ + do { \ + (buf) = (void *)roundup((uintptr_t)(buf), __alignof(*(ptr))); \ + (ptr) = (void *)(buf); \ + (buf) += (size); \ + } while (0) + + GMON_ALLOC(cp, p->kcount, p->kcountsize); + GMON_ALLOC(cp, p->froms, p->fromssize); + GMON_ALLOC(cp, p->tos, p->tossize); + + if (brk(cp)) { warnx("%s: out of memory", __func__); return; } -#ifdef notdef - (void)memset(cp, 0, p->kcountsize + p->fromssize + p->tossize); -#endif - p->tos = (struct tostruct *)(void *)cp; - cp += (size_t)p->tossize; - p->kcount = (u_short *)(void *)cp; - cp += (size_t)p->kcountsize; - p->froms = (u_short *)(void *)cp; + __minbrk = cp; - __minbrk = sbrk((intptr_t)0); p->tos[0].link = 0; o = p->highpc - p->lowpc; @@ -226,17 +230,22 @@ _m_gmon_alloc(void) } else { mutex_unlock(&_gmonlock); cp = mmap(NULL, - (size_t)(sizeof (struct gmonparam) + - _gmonparam.fromssize + _gmonparam.tossize), + (size_t)(__alignof(*p) + sizeof(*p) + + __alignof(*_gmonparam.froms) + _gmonparam.fromssize + + __alignof(*_gmonparam.tos) + _gmonparam.tossize), PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, (off_t)0); - p = (void *)cp; + + GMON_ALLOC(cp, p, sizeof(*p)); *p = _gmonparam; p->state = GMON_PROF_ON; p->kcount = NULL; - cp += sizeof (struct gmonparam); - memset(cp, 0, (size_t)(p->fromssize + p->tossize)); - p->froms = (u_short *)(void *)cp; - p->tos = (struct tostruct *)(void *)(cp + p->fromssize); + + GMON_ALLOC(cp, p->froms, p->fromssize); + memset(p->froms, 0, p->fromssize); + + GMON_ALLOC(cp, p->tos, p->tossize); + memset(p->tos, 0, p->tossize); + mutex_lock(&_gmonlock); p->kcount = (u_short *)(void *)_gmoninuse; _gmoninuse = p;