This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
Hi folks,
it's been a long time since my first approach to submit my Android patch
set.
I re-worked my code 'a bit' and stripped it down to the bare essentials.
The result is attached to this mail. The patch is based on release-3.2.
It basically adds a new configure options: --with-android. This option
makes the configure libelf check optional and disables some parts of
stap{run,io} which depend on libelf.
The result is two binaries, staprun and stapio, which can be executed on
Android.
What do you think about these changes?
Regards,
Alex
--
Technische Universität Dortmund
Alexander Lochmann PGP key: 0xBC3EF6FD
Otto-Hahn-Str. 16 phone: +49.231.7556141
D-44227 Dortmund fax: +49.231.7556116
http://ess.cs.tu-dortmund.de/Staff/al
From 04579cae1833d3889279ea0eb6ecc53c7dbe79cb Mon Sep 17 00:00:00 2001
From: Alexander Lochmann <info@alexander-lochmann.de>
Date: Mon, 2 Apr 2018 20:02:46 +0200
Subject: [PATCH] Make SystemTap compatible with Android
Introduced a new configure option '--with-android' which disables
configure's libelf checks. It disables all libelf-related code in
stap{run,io} as well.
---
build_android.sh | 64 +++++++++++++++++++++++++++++++++++++++++
configure.ac | 21 ++++++++++----
staprun/Makefile.am | 12 ++++++++
staprun/staprun.c | 2 ++
staprun/staprun_funcs.c | 30 +++++++++++++++++++
5 files changed, 124 insertions(+), 5 deletions(-)
create mode 100755 build_android.sh
diff --git a/build_android.sh b/build_android.sh
new file mode 100755
index 000000000..ce25c83c9
--- /dev/null
+++ b/build_android.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+
+BUILD_PREFIX="/data/data/com.systemtap.android/stap/"
+OUTPUT_DIR="android_binaries"
+STAPIO_BIN="staprun/stapio"
+STAPRUN_BIN="staprun/staprun"
+ARCH=${ARCH:-ARM}
+
+case ${ARCH} in
+ARM)
+ COMPILER_PREFIX_LIST=("arm-none-linux-gnueabi" "arm-unknown-linux-gnueabi")
+ ;;
+AARCH64)
+ COMPILER_PREFIX_LIST=("aarch64-linux-gnu")
+ ;;
+esac
+
+function checkCompiler()
+{
+ for cur_compiler_prefix in ${COMPILER_PREFIX_LIST[@]}
+ do
+ RET=`${cur_compiler_prefix}-gcc --version 2>&1`
+ if [ $? -eq 0 ];
+ then
+ COMPILER_PREFIX=${cur_compiler_prefix}
+ return
+ fi
+ done;
+
+ echo "No suitable compiler found. Check your PATH" >&2
+ exit 1
+}
+
+checkCompiler
+
+STAP_ANDROID_PREFIX="/data/data/com.systemtap.android/"
+# A bit of manually tuning of bindir and libexecdir.
+# This way stap{run,io} can both be stored in ${STAP_ANDROID_PREFIX}, and be executed *without* setting the environment variables SYSTEMTAP_STAP{IO,RUN}.
+./configure --prefix=${STAP_ANDROID_PREFIX} --bindir=${STAP_ANDROID_PREFIX}/systemtap --libexecdir=${STAP_ANDROID_PREFIX} --host=arm-none-linux-gnueabi --disable-translator --disable-docs --disable-refdocs --disable-grapher --without-rpm --without-nss --with-android
+
+if [ $? -ne 0 ]; then
+ echo "Error configuring the workspace" >&2
+ exit 1
+fi
+
+make
+
+if [ $? -ne 0 ]; then
+ echo "Error building stap{run,io}" >&2
+ exit 1
+fi
+
+if [ -e $STAPRUN_BIN ] && [ -e $STAPIO_RUN ]; then
+ if [ ! -d $OUTPUT_DIR ]; then
+ mkdir $OUTPUT_DIR
+ fi
+ cp $STAPRUN_BIN $OUTPUT_DIR
+ cp $STAPIO_BIN $OUTPUT_DIR
+else
+ rm ${OUTPUT_DIR}/${STAPRUN_BIN}
+ rm ${OUTPUT_DIR}/${STAPIO_BIN}
+ echo "Some binaries were not created."
+ exit 1
+fi
diff --git a/configure.ac b/configure.ac
index b4dd4afea..5c381b138 100644
--- a/configure.ac
+++ b/configure.ac
@@ -531,7 +531,14 @@ AS_IF([test "x$with_python3" = "xyes"],
[AS_IF([test "x$PYTHON" = "x:"],
[AC_MSG_ERROR([python version 2 is required])],
[AC_SUBST(preferred_python,[$PYTHON])])])
-
+
+AC_ARG_WITH([android],
+ AS_HELP_STRING([--with-android],[]))
+AS_IF([test "x$with_android" = "xyes"],
+ [have_android=yes AC_DEFINE([HAVE_ANDROID], [1], [Define to 1 if you compile for Android.])],
+ [have_android=no])
+AM_CONDITIONAL([HAVE_ANDROID], [test "${have_android}" == "yes"])
+
dnl Handle elfutils. If '--with-elfutils=DIR' wasn't specified, used
dnl the system's elfutils.
build_elfutils=no
@@ -580,10 +587,14 @@ AC_MSG_NOTICE([stap will link $stap_LIBS])
if test $build_elfutils = no; then
save_LIBS="$LIBS"
dnl this will only succeed with elfutils 0.142+
- AC_CHECK_LIB(elf,elf_getshdrstrndx,[],[
- AC_MSG_FAILURE([libelf too old, need 0.142+])])
- staprun_LIBS="$staprun_LIBS -lelf"
- stapbpf_LIBS="$stapbpf_LIBS -lelf"
+ if test "${have_android}" == "bo"; then
+ AC_CHECK_LIB(elf,elf_getshdrstrndx,
+ [staprun_LIBS="$staprun_LIBS -lelf"
+ LIBS="$save_LIBS"],
+ [AC_MSG_FAILURE([libelf too old, need 0.142+])])
+ staprun_LIBS="$staprun_LIBS -lelf"
+ stapbpf_LIBS="$stapbpf_LIBS -lelf"
+ fi
LIBS="$save_LIBS"
else
# We built our own and staprun_LDFLAGS points at the install.
diff --git a/staprun/Makefile.am b/staprun/Makefile.am
index 4073aa01c..9dfe4fb8a 100644
--- a/staprun/Makefile.am
+++ b/staprun/Makefile.am
@@ -29,6 +29,9 @@ staprun_CXXFLAGS = $(AM_CXXFLAGS) -DSINGLE_THREADED
staprun_CPPFLAGS = $(AM_CPPFLAGS)
staprun_LDADD = libstrfloctime.a $(staprun_LIBS)
staprun_LDFLAGS = $(AM_LDFLAGS)
+if HAVE_ANDROID
+staprun_LDFLAGS += -static
+endif
if BUILD_ELFUTILS
staprun_CPPFLAGS += -I../include-elfutils
staprun_LDFLAGS += -L../lib-elfutils -Wl,-rpath-link,lib-elfutils \
@@ -43,6 +46,9 @@ staprun_LDADD += $(nss_LIBS)
endif
stapio_SOURCES = stapio.c mainloop.c common.c ctl.c relay.c relay_old.c monitor.c
+if HAVE_ANDROID
+stapio_LDFLAGS = -static
+endif
stapio_LDADD = libstrfloctime.a -lpthread
if HAVE_MONITOR_LIBS
@@ -54,11 +60,17 @@ man_MANS = staprun.8
stap_merge_SOURCES = stap_merge.c
stap_merge_CFLAGS = $(AM_CFLAGS)
stap_merge_LDFLAGS = $(AM_LDFLAGS)
+if HAVE_ANDROID
+stap_merge_LDFLAGS += -static
+endif
stap_merge_LDADD =
stapsh_SOURCES = stapsh.c
stapsh_CFLAGS = $(AM_CFLAGS)
stapsh_LDFLAGS = $(AM_LDFLAGS)
+if HAVE_ANDROID
+stapsh_LDFLAGS += -static
+endif
stapsh_LDADD =
BUILT_SOURCES =
diff --git a/staprun/staprun.c b/staprun/staprun.c
index 79d82f3df..26c201747 100644
--- a/staprun/staprun.c
+++ b/staprun/staprun.c
@@ -358,8 +358,10 @@ int init_staprun(void)
disable_kprobes_optimization();
if (insert_stap_module(& user_credentials) < 0) {
+#ifdef HAVE_ANDROID
if(!rename_mod && errno == EEXIST)
err("Rerun with staprun option '-R' to rename this module.\n");
+#endif
return -1;
}
rc = init_ctl_channel (modname, 0);
diff --git a/staprun/staprun_funcs.c b/staprun/staprun_funcs.c
index a938e0737..4d4c60037 100644
--- a/staprun/staprun_funcs.c
+++ b/staprun/staprun_funcs.c
@@ -19,10 +19,12 @@
#include <pwd.h>
#include <assert.h>
+#ifndef HAVE_ANDROID
/* The module-renaming facility only works with new enough
elfutils: 0.142+. */
#include <libelf.h>
#include <gelf.h>
+#endif
#include <math.h>
@@ -206,6 +208,7 @@ int insert_module(
return 0;
}
+#ifndef HAVE_ANDROID
static Elf_Scn *
find_section_in_module(const void* module_file, const __off_t st_size, const char *section_name)
{
@@ -244,10 +247,12 @@ find_section_in_module(const void* module_file, const __off_t st_size, const cha
}
return scn;
}
+#endif /* HAVE_ANDROID */
int
rename_module(void* module_file, const __off_t st_size)
{
+#ifndef HAVE_ANDROID
int length_to_replace;
char newname[MODULE_NAME_LEN];
char *p;
@@ -305,6 +310,14 @@ rename_module(void* module_file, const __off_t st_size)
}
_err("Could not find old name to replace!\n");
return -1;
+#else
+ /* Old or no elfutils? Pretend to have renamed. This means a
+ greater likelihood for module-name collisions, but so be
+ it. */
+ (void) module_file;
+ (void) st_size;
+ return 0;
+#endif /* HAVE_ANDROID */
}
@@ -582,6 +595,22 @@ static privilege_t get_module_required_credentials (
const __off_t st_size __attribute__ ((unused))
)
{
+#ifdef HAVE_ANDROID
+ /* Without the proper ELF support, we can't determine the credentials required to run this
+ module. However, we know that it has been correctly signed (we only check privilege
+ credentials for correctly signed modules). It is therefore either
+ a) a dual-privilege-level era module compiled with stapusr privileges enforced or,
+ b) a multi-privilege-level era module with built-in privilege level checking.
+ In either case, we can load it for stapusr level users and above. In case a, it requires
+ exactly that privilege level. In case b, the module will self check against the user's
+ actual privilege level.
+ */
+ if (verbose >= 1) {
+ err ("Unable to determine the privilege level required for the module %s. Assuming %s.\n",
+ module_path, pr_name (pr_stapusr));
+ }
+ return pr_stapusr;
+#else
Elf_Scn *scn = 0;
Elf_Data *data = 0;
GElf_Shdr shdr;
@@ -666,6 +695,7 @@ static privilege_t get_module_required_credentials (
/* ALl is ok. Return the extracted privilege data. */
return privilege;
+#endif /* HAVE_ANDROID */
}
/*
--
2.17.0
Attachment:
signature.asc
Description: OpenPGP digital signature
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |