From patchwork Thu Oct 12 02:19:50 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 824651 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-85685-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="tDMo+N+G"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3yCF1R4lMGz9t2Z for ; Thu, 12 Oct 2017 13:20:11 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:subject:message-id:mime-version :content-type; q=dns; s=default; b=qMJsJZEk5mE0p7JC4nHa1iiP2bRS/ bGIS1JGSRntj0IMWkOkqRVju3TjvEsL73ed8MKMSnwerJc6tXZPjpR65UtNrFM2D UAAlBaEzccPiR0UMEJs+PcNCeuhPgeeHzF00k+IjOO312PDvFooFDAuyXytKZU9O 8hhCMQ3MNq4NTc= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:subject:message-id:mime-version :content-type; s=default; bh=54hrPqgrjUkhWtlCi9fm9XFnaMo=; b=tDM o+N+GBa/vIE6HtgED2XuLgaPxOqGKm4dorH1VFtxzlA6TGtGpudKGsEcOuxhlGlq UXr7VmxDsNtOfwqJIuhZfzKRf0wD9eMVQ9fbbzomKdYjKM1CGGZiRPrwBPaIjgEb yLY/YFJ/uUXbjPzUUfIx/3t34cN/VXTZSynyV3r8= Received: (qmail 6996 invoked by alias); 12 Oct 2017 02:20:02 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 6365 invoked by uid 89); 12 Oct 2017 02:20:01 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.0 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=ham version=3.3.2 spammy=PCs X-HELO: mail-qt0-f196.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-disposition:user-agent; bh=feXCHriDwUr3XbfbM1gM8Vl1KhSYqcoInHo/uDBjR3o=; b=IpDhn6LlYUxiuKQ3jjBOiCqxVPw816SuBVQ9FHPGjw99vO49IBdRcKWdPMW0ghgiTL hBRoq2q2Ag1xeqUSDh5+36ScB9v+Hm28Az2mFLDkMwFOCVaUhV6g4fQYEPO9ffy8Bt4O TFpEWWTzpIbipm3/mvKrb5LLg1L/dwAyoc+Io9n0D0QDa0jvzwQbiVpW6v0p2ekcF2ra +wN956Us5ScJ7JiF9HdRwmxPFxGeE+NSmRoiG6/NoRl5YJTtvZyijdNd3dXtjKfGVQ0O TS8b3MHzkxEPG91VbM80Dck3AhI49neOARWW5UE3XAzjCQOCocPPdFKuENn+Yk1S6FYS l4lg== X-Gm-Message-State: AMCzsaXc9dnNLOQ+IyLgV0ZPa3r4iwfKZLC+kPSto/i34n3qPiEXHz50 By9lcCjgCZXKOyhz0lGcIIB/OEvF X-Google-Smtp-Source: AOwi7QDkjQvX4Vn2TSaDv/WUPrlSF7gdaMpuj6lZPHe9AYQumLCGMQIlPHl/XOfs1+JTbrxC99neEw== X-Received: by 10.129.82.206 with SMTP id g197mr904135ywb.319.1507774797863; Wed, 11 Oct 2017 19:19:57 -0700 (PDT) Date: Wed, 11 Oct 2017 19:19:50 -0700 From: "H.J. Lu" To: GNU C Library Subject: [PATCH] Support profiling PIE [BZ #22284] Message-ID: <20171012021950.GA21344@gmail.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.9.1 (2017-09-22) Since PIE can be loaded at any address, we need to subtract load address from PCs. Tested on i686 and x86-64. OK for master? H.J. Reviewed-by: Carlos O'Donell --- [BZ #22284] * gmon/Makefile [$(have-fpie)$(build-shared) == yesyes] (tests, tests-pie): Add tst-gmon-pie. (CFLAGS-tst-gmon-pie.c): New. (CRT-tst-gmon-pie): Likewise. (tst-gmon-pie-ENV): Likewise. [$(have-fpie)$(build-shared) == yesyes] (tests-special): Likewise. ($(objpfx)tst-gmon-pie.out): Likewise. (clean-tst-gmon-pie-data): Likewise. ($(objpfx)tst-gmon-pie-gprof.out): Likewise. * gmon/gmon.c [PIC]: Include . [PIC] (callback): New function. (write_hist): Add an argument for load address. Subtract load address from PCs. (write_call_graph): Likewise. (write_gmon): Call __dl_iterate_phdr to get load address, pass it to write_hist and write_call_graph. --- gmon/Makefile | 21 +++++++++++++++++++++ gmon/gmon.c | 44 ++++++++++++++++++++++++++++++++++---------- gmon/tst-gmon-pie.c | 1 + 3 files changed, 56 insertions(+), 10 deletions(-) create mode 100644 gmon/tst-gmon-pie.c diff --git a/gmon/Makefile b/gmon/Makefile index 79e29d188f..2cd077dece 100644 --- a/gmon/Makefile +++ b/gmon/Makefile @@ -33,6 +33,11 @@ tests-static += tst-profile-static LDFLAGS-tst-profile-static = -profile endif +ifeq (yesyes,$(have-fpie)$(build-shared)) +tests += tst-gmon-pie +tests-pie += tst-gmon-pie +endif + # The mcount code won't work without a frame pointer. CFLAGS-mcount.c := -fno-omit-frame-pointer @@ -44,6 +49,14 @@ ifeq ($(run-built-tests),yes) tests-special += $(objpfx)tst-gmon-gprof.out endif +CFLAGS-tst-gmon-pie.c := $(PIE-ccflag) -fno-omit-frame-pointer -pg +CRT-tst-gmon-pie := $(csu-objpfx)gcrt1.o +tst-gmon-pie-ENV := GMON_OUT_PREFIX=$(objpfx)tst-gmon-pie.data +ifeq ($(run-built-tests),yes) +tests-special += $(objpfx)tst-gmon-pie-gprof.out +endif + + include ../Rules # We cannot compile mcount.c with -pg because that would @@ -69,3 +82,11 @@ clean-tst-gmon-data: $(objpfx)tst-gmon-gprof.out: tst-gmon-gprof.sh $(objpfx)tst-gmon.out $(SHELL) $< $(GPROF) $(objpfx)tst-gmon $(objpfx)tst-gmon.data.* > $@; \ $(evaluate-test) + +$(objpfx)tst-gmon-pie.out: clean-tst-gmon-pie-data +clean-tst-gmon-pie-data: + rm -f $(objpfx)tst-gmon-pie.data.* + +$(objpfx)tst-gmon-pie-gprof.out: tst-gmon-gprof.sh $(objpfx)tst-gmon-pie.out + $(SHELL) $< $(GPROF) $(objpfx)tst-gmon-pie $(objpfx)tst-gmon-pie.data.* > $@; \ + $(evaluate-test) diff --git a/gmon/gmon.c b/gmon/gmon.c index f1aa3b776c..5f569cc994 100644 --- a/gmon/gmon.c +++ b/gmon/gmon.c @@ -46,6 +46,23 @@ #include #include +#ifdef PIC +# include + +static int +callback (struct dl_phdr_info *info, size_t size, void *data) +{ + u_long *load_address = data; + + if (info->dlpi_name[0] == '\0') + { + *load_address = (u_long) info->dlpi_addr; + return 1; + } + + return 0; +} +#endif /* Head of basic-block list or NULL. */ struct __bb *__bb_head attribute_hidden; @@ -63,8 +80,8 @@ static int s_scale; void moncontrol (int mode); void __moncontrol (int mode); libc_hidden_proto (__moncontrol) -static void write_hist (int fd); -static void write_call_graph (int fd); +static void write_hist (int fd, u_long load_address); +static void write_call_graph (int fd, u_long load_address); static void write_bb_counts (int fd); /* @@ -173,7 +190,7 @@ weak_alias (__monstartup, monstartup) static void -write_hist (int fd) +write_hist (int fd, u_long load_address) { u_char tag = GMON_TAG_TIME_HIST; @@ -210,8 +227,8 @@ write_hist (int fd) != offsetof (struct gmon_hist_hdr, dimen_abbrev))) abort (); - thdr.low_pc = (char *) _gmonparam.lowpc; - thdr.high_pc = (char *) _gmonparam.highpc; + thdr.low_pc = (char *) _gmonparam.lowpc - load_address; + thdr.high_pc = (char *) _gmonparam.highpc - load_address; thdr.hist_size = _gmonparam.kcountsize / sizeof (HISTCOUNTER); thdr.prof_rate = __profile_frequency (); strncpy (thdr.dimen, "seconds", sizeof (thdr.dimen)); @@ -223,7 +240,7 @@ write_hist (int fd) static void -write_call_graph (int fd) +write_call_graph (int fd, u_long load_address) { #define NARCS_PER_WRITEV 32 u_char tag = GMON_TAG_CG_ARC; @@ -266,8 +283,9 @@ write_call_graph (int fd) } arc; - arc.frompc = (char *) frompc; - arc.selfpc = (char *) _gmonparam.tos[to_index].selfpc; + arc.frompc = (char *) frompc - load_address; + arc.selfpc = ((char *) _gmonparam.tos[to_index].selfpc + - load_address); arc.count = _gmonparam.tos[to_index].count; memcpy (raw_arc + nfilled, &arc, sizeof (raw_arc [0])); @@ -376,11 +394,17 @@ write_gmon (void) memset (ghdr.spare, '\0', sizeof (ghdr.spare)); __write_nocancel (fd, &ghdr, sizeof (struct gmon_hdr)); + /* Get load_address to profile PIE. */ + u_long load_address = 0; +#ifdef PIC + __dl_iterate_phdr (callback, &load_address); +#endif + /* write PC histogram: */ - write_hist (fd); + write_hist (fd, load_address); /* write call-graph: */ - write_call_graph (fd); + write_call_graph (fd, load_address); /* write basic-block execution counts: */ write_bb_counts (fd); diff --git a/gmon/tst-gmon-pie.c b/gmon/tst-gmon-pie.c new file mode 100644 index 0000000000..1eef2583b6 --- /dev/null +++ b/gmon/tst-gmon-pie.c @@ -0,0 +1 @@ +#include "tst-gmon.c"