From patchwork Sat Jan 10 01:42:42 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 427307 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from hemlock.osuosl.org (hemlock.osuosl.org [140.211.166.133]) by ozlabs.org (Postfix) with ESMTP id 0096014007D for ; Sat, 10 Jan 2015 12:43:04 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 2EE0792146; Sat, 10 Jan 2015 01:43:03 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Lo-chEqnhpvE; Sat, 10 Jan 2015 01:43:02 +0000 (UTC) Received: from ash.osuosl.org (ash.osuosl.org [140.211.166.34]) by hemlock.osuosl.org (Postfix) with ESMTP id 91B6892102; Sat, 10 Jan 2015 01:43:02 +0000 (UTC) X-Original-To: uclibc@lists.busybox.net Delivered-To: uclibc@osuosl.org Received: from silver.osuosl.org (silver.osuosl.org [140.211.166.136]) by ash.osuosl.org (Postfix) with ESMTP id 43CBF1BFA7E for ; Sat, 10 Jan 2015 01:43:01 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 3B22732EF5 for ; Sat, 10 Jan 2015 01:43:01 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id NlZJoaJ06LXz for ; Sat, 10 Jan 2015 01:43:00 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail-la0-f54.google.com (mail-la0-f54.google.com [209.85.215.54]) by silver.osuosl.org (Postfix) with ESMTPS id 0EB2132ED1 for ; Sat, 10 Jan 2015 01:43:00 +0000 (UTC) Received: by mail-la0-f54.google.com with SMTP id pv20so17169864lab.13 for ; Fri, 09 Jan 2015 17:42:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=gdOp3gq/QVHO3ZOJ1rvQqm6N2u4cQK5zpUopqTgOTJs=; b=mtGYPEuaB367V39f32mmOZPl8UA0U0UFMDLhIV3Bce8EyR5n3VcKUCJgb7E+6sTTh2 W/m2gOKxdwi7y4L6Fx3YeYMEqF5VOiIQSKPc+/Lu2eofkwOsiIBTrbUAWJtyZmvrxaFM ynnd650aG0UwfioaT3f5/Y0UfKuWPUZQUlTAcjRjdnykeW9Jexy85OZz8462ArqdloS3 XY2XGCrC/0sSqWKD64DHGD/cOJHiVjQJ0Vgy18Pv1ZTvzK9nq0ffWkaEzXqaY/+FN+Vk GrT1u9GXbWmzhzZ2r6+CYv/8/RKfGPD+yF+Se/cPjY9G80D+uQAqWtbp36mmsvLLf61N HAgw== X-Received: by 10.152.22.67 with SMTP id b3mr24991379laf.82.1420854178124; Fri, 09 Jan 2015 17:42:58 -0800 (PST) Received: from octofox.metropolis ([5.19.183.212]) by mx.google.com with ESMTPSA id jg8sm2239273lbc.0.2015.01.09.17.42.55 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 09 Jan 2015 17:42:57 -0800 (PST) From: Max Filippov To: uclibc@uclibc.org Subject: [PATCH v3] xtensa: ldso: coalesce dl_mprotect address ranges Date: Sat, 10 Jan 2015 04:42:42 +0300 Message-Id: <1420854162-29687-1-git-send-email-jcmvbkbc@gmail.com> X-Mailer: git-send-email 1.8.1.4 Cc: linux-xtensa@linux-xtensa.org X-BeenThere: uclibc@uclibc.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "Discussion and development of uClibc \(the embedded C library\)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: uclibc-bounces@uclibc.org Sender: "uClibc" This noticeably lowers the number of mprotect calls at program startup, e.g. for busybox: 7 calls vs 1835 calls. Signed-off-by: Max Filippov --- Changes v2->v3: - coalesce address ranges that overlap in any way, not only at the end of the existing range. Changes v1->v2: - initialize prev_got_start and prev_got_end in INIT_GOT as well. ldso/ldso/xtensa/dl-startup.h | 20 +++++++++++++++++++- ldso/ldso/xtensa/dl-sysdep.h | 24 +++++++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/ldso/ldso/xtensa/dl-startup.h b/ldso/ldso/xtensa/dl-startup.h index b135a4c..0c28d5e 100644 --- a/ldso/ldso/xtensa/dl-startup.h +++ b/ldso/ldso/xtensa/dl-startup.h @@ -83,6 +83,7 @@ do { \ unsigned long l_addr = tpnt->loadaddr; \ Elf32_Word relative_count; \ unsigned long rel_addr; \ + Elf32_Addr prev_got_start = 0, prev_got_end = 0; \ int x; \ \ got_loc = (xtensa_got_location *) \ @@ -93,7 +94,24 @@ do { \ got_start = got_loc[x].offset & ~(PAGE_SIZE - 1); \ got_end = ((got_loc[x].offset + got_loc[x].length + PAGE_SIZE - 1) \ & ~(PAGE_SIZE - 1)); \ - _dl_mprotect ((void *)(got_start + l_addr), got_end - got_start, \ + if (got_end >= prev_got_start && got_start <= prev_got_end) { \ + if (got_end > prev_got_end) \ + prev_got_end = got_end; \ + if (got_start < prev_got_start) \ + prev_got_start = got_start; \ + continue; \ + } else if (prev_got_start != prev_got_end) { \ + _dl_mprotect ((void *)(prev_got_start + l_addr), \ + prev_got_end - prev_got_start, \ + PROT_READ | PROT_WRITE | PROT_EXEC); \ + } \ + prev_got_start = got_start; \ + prev_got_end = got_end; \ + } \ +\ + if (prev_got_start != prev_got_end) { \ + _dl_mprotect ((void *)(prev_got_start + l_addr), \ + prev_got_end - prev_got_start, \ PROT_READ | PROT_WRITE | PROT_EXEC); \ } \ \ diff --git a/ldso/ldso/xtensa/dl-sysdep.h b/ldso/ldso/xtensa/dl-sysdep.h index a0ed4e5..5f8bcb0 100644 --- a/ldso/ldso/xtensa/dl-sysdep.h +++ b/ldso/ldso/xtensa/dl-sysdep.h @@ -36,6 +36,7 @@ typedef struct xtensa_got_location_struct { do { \ xtensa_got_location *got_loc; \ Elf32_Addr l_addr = MODULE->loadaddr; \ + Elf32_Addr prev_got_start = 0, prev_got_end = 0; \ int x; \ \ got_loc = (xtensa_got_location *) \ @@ -47,7 +48,28 @@ typedef struct xtensa_got_location_struct { got_start = got_loc[x].offset & ~(PAGE_SIZE - 1); \ got_end = ((got_loc[x].offset + got_loc[x].length + PAGE_SIZE - 1) \ & ~(PAGE_SIZE - 1)); \ - _dl_mprotect ((void *)(got_start + l_addr) , got_end - got_start, \ + if (got_end >= prev_got_start && got_start <= prev_got_end) \ + { \ + if (got_end > prev_got_end) \ + prev_got_end = got_end; \ + if (got_start < prev_got_start) \ + prev_got_start = got_start; \ + continue; \ + } \ + else if (prev_got_start != prev_got_end) \ + { \ + _dl_mprotect ((void *)(prev_got_start + l_addr), \ + prev_got_end - prev_got_start, \ + PROT_READ | PROT_WRITE | PROT_EXEC); \ + } \ + prev_got_start = got_start; \ + prev_got_end = got_end; \ + } \ + \ + if (prev_got_start != prev_got_end) \ + { \ + _dl_mprotect ((void *)(prev_got_start + l_addr), \ + prev_got_end - prev_got_start, \ PROT_READ | PROT_WRITE | PROT_EXEC); \ } \ \