From patchwork Tue Apr 8 07:04:11 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Kamensky X-Patchwork-Id: 3949631 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 7250DBFF02 for ; Tue, 8 Apr 2014 15:35:20 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 68D87203B8 for ; Tue, 8 Apr 2014 15:35:19 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 30919203B7 for ; Tue, 8 Apr 2014 15:35:18 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WXY29-0002x4-CS; Tue, 08 Apr 2014 15:33:57 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WXY21-0006Xc-K9; Tue, 08 Apr 2014 15:33:49 +0000 Received: from bombadil.infradead.org ([2001:1868:205::9]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WXXk8-0003gg-4w for linux-arm-kernel@merlin.infradead.org; Tue, 08 Apr 2014 15:15:20 +0000 Received: from mail-pd0-f170.google.com ([209.85.192.170]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WXQ5f-0002ls-7P for linux-arm-kernel@lists.infradead.org; Tue, 08 Apr 2014 07:05:04 +0000 Received: by mail-pd0-f170.google.com with SMTP id v10so602656pde.29 for ; Tue, 08 Apr 2014 00:04:36 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=EAbRuh8S8NYYhv9KzRQJYf8Fk//aUBFUC+vHXSvlP9s=; b=UofOaE5A4DtaO3+/Rr4fN/FiF3voeztABeSw7iewRw1ePWjlCOhvzUUkWAOY0/4XsW BURhtbzTd0aW5Gc9EpTPuKwA499Bd098t1hulIsiQg3yeI7caGQgOQuZdNyWifQmvYQs 4eXCEFOUHTtf4UGZecCDnrusP+XEDGApHze1YFbHL5TICeHiQ28Tn1EnNrsvhV2Syt6Z O3e7GI8hVhmgIFiB4o0fuVrwDgljmUyKlwPoCU2Z1blOm50Lvv+gP6WTCiW9Yd3g0/EX lLBU2EnxSYa0AU1hq/1o+TodWcjWrDY34ELXijPZbXYfui/LKaEeSsG1knvyNEyBY8a3 RpFA== X-Gm-Message-State: ALoCoQmOs1FbJd7E+l/Uvvrps5wPAvaLOk9HQVNzhKUIUrqCXjH+jweQN8Cl1KssB/k+qCCRLShx X-Received: by 10.68.244.229 with SMTP id xj5mr2555840pbc.108.1396940676525; Tue, 08 Apr 2014 00:04:36 -0700 (PDT) Received: from kamensky-w530.cisco.com (128-107-239-233.cisco.com. [128.107.239.233]) by mx.google.com with ESMTPSA id tu3sm5921675pab.1.2014.04.08.00.04.34 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 08 Apr 2014 00:04:35 -0700 (PDT) From: Victor Kamensky To: systemtap@sourceware.org, Dave.Martin@arm.com Subject: [PATCH] systemtap: need to use kallsyms_lookup_funcptr with arm thumb2 kernel Date: Tue, 8 Apr 2014 00:04:11 -0700 Message-Id: <1396940651-19013-2-git-send-email-victor.kamensky@linaro.org> X-Mailer: git-send-email 1.8.1.4 In-Reply-To: <1396940651-19013-1-git-send-email-victor.kamensky@linaro.org> References: <1396940651-19013-1-git-send-email-victor.kamensky@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140408_000503_312011_4A88B945 X-CRM114-Status: GOOD ( 15.72 ) X-Spam-Score: -0.0 (/) Cc: tixy@linaro.org, taras.kondratiuk@linaro.org, dave.long@linaro.org, linux-arm-kernel@lists.infradead.org, Victor Kamensky X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Thumb2 function pointer should have bit 0 set when called, even if function text is aligned with 2 or 4 bytes. Current systemtap runtime uses kallsyms_lookup_name to get function pointer, cast it, and calls it. It does not work in case of arm CONFIG_THUMB2_KERNEL. The patch add simple wrapper on top of kallsyms_lookup_name, which in case of CONFIG_THUMB2_KERNEL set bit 0 of returned function address. In all other case it just returns result of kallsyms_lookup_name call. In case if/when kernel will provide similar to kallsyms_lookup_funcptr functionality in kernel itself remove/rework this change. Signed-off-by: Victor Kamensky --- runtime/linux/kallsyms_wrapper.h | 28 ++++++++++++++++++++++++++++ runtime/linux/runtime.h | 2 ++ runtime/stp_task_work.c | 4 ++-- runtime/stp_utrace.c | 6 +++--- runtime/transport/transport.c | 12 ++++++------ 5 files changed, 41 insertions(+), 11 deletions(-) create mode 100644 runtime/linux/kallsyms_wrapper.h diff --git a/runtime/linux/kallsyms_wrapper.h b/runtime/linux/kallsyms_wrapper.h new file mode 100644 index 0000000..9e698ab --- /dev/null +++ b/runtime/linux/kallsyms_wrapper.h @@ -0,0 +1,28 @@ +#ifndef _KALLSYMS_WRAPPER_H +#define _KALLSYMS_WRAPPER_H + +/* + * Copyright (C) 2011 Avik Sil (avik.sil at linaro.org) + * + * wrapper around kallsyms_lookup_name. Implements arch-dependent code for + * arches where the address of the start of the function body is different + * from the pointer which can be used to call the function, e.g. ARM THUMB2. + * + * Dual LGPL v2.1/GPL v2 license. +*/ + +static inline +unsigned long kallsyms_lookup_funcptr(const char *name) +{ + unsigned long addr; + + addr = kallsyms_lookup_name(name); +#ifdef CONFIG_ARM +#ifdef CONFIG_THUMB2_KERNEL + if (addr) + addr |= 1; /* set bit 0 in address for thumb mode */ +#endif +#endif + return addr; +} +#endif /* _KALLSYMS_WRAPPER_H */ diff --git a/runtime/linux/runtime.h b/runtime/linux/runtime.h index 76dbea4..0ae1ffa 100644 --- a/runtime/linux/runtime.h +++ b/runtime/linux/runtime.h @@ -190,6 +190,8 @@ static void *kallsyms_signal_wake_up; static void *kallsyms___lock_task_sighand; #endif +#include "kallsyms_wrapper.h" + #include "access_process_vm.h" #include "loc2c-runtime.h" diff --git a/runtime/stp_task_work.c b/runtime/stp_task_work.c index 93f56a5..246d648 100644 --- a/runtime/stp_task_work.c +++ b/runtime/stp_task_work.c @@ -25,12 +25,12 @@ stp_task_work_init(void) #if !defined(STAPCONF_TASK_WORK_ADD_EXPORTED) /* The task_work_add()/task_work_cancel() functions aren't * exported. Look up those function addresses. */ - kallsyms_task_work_add = (void *)kallsyms_lookup_name("task_work_add"); + kallsyms_task_work_add = (void *)kallsyms_lookup_funcptr("task_work_add"); if (kallsyms_task_work_add == NULL) { _stp_error("Can't resolve task_work_add!"); return -ENOENT; } - kallsyms_task_work_cancel = (void *)kallsyms_lookup_name("task_work_cancel"); + kallsyms_task_work_cancel = (void *)kallsyms_lookup_funcptr("task_work_cancel"); if (kallsyms_task_work_cancel == NULL) { _stp_error("Can't resolve task_work_cancel!"); return -ENOENT; diff --git a/runtime/stp_utrace.c b/runtime/stp_utrace.c index a6f363d..056f1ab 100644 --- a/runtime/stp_utrace.c +++ b/runtime/stp_utrace.c @@ -191,12 +191,12 @@ static int utrace_init(void) /* The signal_wake_up_state() function (which replaces * signal_wake_up() in newer kernels) isn't exported. Look up * that function address. */ - kallsyms_signal_wake_up_state = (void *)kallsyms_lookup_name("signal_wake_up_state"); + kallsyms_signal_wake_up_state = (void *)kallsyms_lookup_funcptr("signal_wake_up_state"); #endif #if !defined(STAPCONF_SIGNAL_WAKE_UP_EXPORTED) /* The signal_wake_up() function isn't exported. Look up that * function address. */ - kallsyms_signal_wake_up = (void *)kallsyms_lookup_name("signal_wake_up"); + kallsyms_signal_wake_up = (void *)kallsyms_lookup_funcptr("signal_wake_up"); #endif #if (!defined(STAPCONF_SIGNAL_WAKE_UP_STATE_EXPORTED) \ && !defined(STAPCONF_SIGNAL_WAKE_UP_EXPORTED)) @@ -209,7 +209,7 @@ static int utrace_init(void) #if !defined(STAPCONF___LOCK_TASK_SIGHAND_EXPORTED) /* The __lock_task_sighand() function isn't exported. Look up * that function address. */ - kallsyms___lock_task_sighand = (void *)kallsyms_lookup_name("__lock_task_sighand"); + kallsyms___lock_task_sighand = (void *)kallsyms_lookup_funcptr("__lock_task_sighand"); if (kallsyms___lock_task_sighand == NULL) { _stp_error("Can't resolve __lock_task_sighand!"); goto error; diff --git a/runtime/transport/transport.c b/runtime/transport/transport.c index 0ddf514..bbad89e 100644 --- a/runtime/transport/transport.c +++ b/runtime/transport/transport.c @@ -352,7 +352,7 @@ static int _stp_transport_init(void) /* PR13489, missing inode-uprobes symbol-export workaround */ #if !defined(STAPCONF_TASK_USER_REGSET_VIEW_EXPORTED) && !defined(STAPCONF_UTRACE_REGSET) /* RHEL5 era utrace */ - kallsyms_task_user_regset_view = (void*) kallsyms_lookup_name ("task_user_regset_view"); + kallsyms_task_user_regset_view = (void*) kallsyms_lookup_funcptr ("task_user_regset_view"); /* There exist interesting kernel versions without task_user_regset_view(), like ARM before 3.0. For these kernels, uprobes etc. are out of the question, but plain kernel stap works fine. All we have to accomplish is have the loc2c runtime code compile. For that, it's enough @@ -363,9 +363,9 @@ static int _stp_transport_init(void) #endif #if defined(CONFIG_UPROBES) // i.e., kernel-embedded uprobes #if !defined(STAPCONF_UPROBE_REGISTER_EXPORTED) - kallsyms_uprobe_register = (void*) kallsyms_lookup_name ("uprobe_register"); + kallsyms_uprobe_register = (void*) kallsyms_lookup_funcptr ("uprobe_register"); if (kallsyms_uprobe_register == NULL) { - kallsyms_uprobe_register = (void*) kallsyms_lookup_name ("register_uprobe"); + kallsyms_uprobe_register = (void*) kallsyms_lookup_funcptr ("register_uprobe"); } if (kallsyms_uprobe_register == NULL) { printk(KERN_ERR "%s can't resolve uprobe_register!", THIS_MODULE->name); @@ -373,9 +373,9 @@ static int _stp_transport_init(void) } #endif #if !defined(STAPCONF_UPROBE_UNREGISTER_EXPORTED) - kallsyms_uprobe_unregister = (void*) kallsyms_lookup_name ("uprobe_unregister"); + kallsyms_uprobe_unregister = (void*) kallsyms_lookup_funcptr ("uprobe_unregister"); if (kallsyms_uprobe_unregister == NULL) { - kallsyms_uprobe_unregister = (void*) kallsyms_lookup_name ("unregister_uprobe"); + kallsyms_uprobe_unregister = (void*) kallsyms_lookup_funcptr ("unregister_uprobe"); } if (kallsyms_uprobe_unregister == NULL) { printk(KERN_ERR "%s can't resolve uprobe_unregister!", THIS_MODULE->name); @@ -383,7 +383,7 @@ static int _stp_transport_init(void) } #endif #if !defined(STAPCONF_UPROBE_GET_SWBP_ADDR_EXPORTED) - kallsyms_uprobe_get_swbp_addr = (void*) kallsyms_lookup_name ("uprobe_get_swbp_addr"); + kallsyms_uprobe_get_swbp_addr = (void*) kallsyms_lookup_funcptr ("uprobe_get_swbp_addr"); if (kallsyms_uprobe_get_swbp_addr == NULL) { printk(KERN_ERR "%s can't resolve uprobe_get_swbp_addr!", THIS_MODULE->name); goto err0;