From d6bbea2acf3e69afe0ac87105d6e443a19c43d14 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Wed, 1 Jan 2020 00:15:04 -0500 Subject: fix fdpic regression in dynamic linker with overly smart compilers at least gcc 9 broke execution of DT_INIT/DT_FINI for fdpic archs (presently only sh) by recognizing that the stores to the compound-literal function descriptor constructed to call them were dead stores. there's no way to make a "may_alias function", so instead launder the descriptor through an asm-statement barrier. in practice just making the compound literal volatile seemed to have worked too, but this should be less of a hack and more accurately convey the semantics of what transformations are not valid. --- ldso/dynlink.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'ldso') diff --git a/ldso/dynlink.c b/ldso/dynlink.c index acd2b20a..a18461e3 100644 --- a/ldso/dynlink.c +++ b/ldso/dynlink.c @@ -185,8 +185,14 @@ static void *laddr_pg(const struct dso *p, size_t v) } return (void *)(v - p->loadmap->segs[j].p_vaddr + p->loadmap->segs[j].addr); } -#define fpaddr(p, v) ((void (*)())&(struct funcdesc){ \ - laddr(p, v), (p)->got }) +static void (*fdbarrier(void *p))() +{ + void (*fd)(); + __asm__("" : "=r"(fd) : "0"(p)); + return fd; +} +#define fpaddr(p, v) fdbarrier((&(struct funcdesc){ \ + laddr(p, v), (p)->got })) #else #define laddr(p, v) (void *)((p)->base + (v)) #define laddr_pg(p, v) laddr(p, v) -- cgit v1.2.1