From 24e46a597115c9c4f4f9c113ed0a4f45b872b596 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Thu, 29 Feb 2024 02:36:05 -0800 Subject: [PATCH] Build magiskboot with crt0 --- build.py | 16 ++++++--------- native/build.gradle.kts | 3 ++- native/src/Android.mk | 6 ++++++ native/src/base/files.cpp | 16 ++++----------- native/src/base/misc.cpp | 34 ++++++++++++++++++++++++++++++++ native/src/boot/main.cpp | 5 +++++ native/src/external/crt0 | 2 +- native/src/sepolicy/policydb.cpp | 10 +++------- 8 files changed, 61 insertions(+), 31 deletions(-) diff --git a/build.py b/build.py index 7a29de90e..4d901d6ac 100755 --- a/build.py +++ b/build.py @@ -400,31 +400,27 @@ def build_binary(args): flag += " B_POLICY=1" clean = True - if "test" in args.target: - flag += " B_TEST=1" - if "magiskinit" in args.target: flag += " B_PRELOAD=1" if "resetprop" in args.target: flag += " B_PROP=1" - if "magiskboot" in args.target: - flag += " B_BOOT=1" - if flag: run_ndk_build(flag) - # magiskinit embeds preload.so - flag = "" if "magiskinit" in args.target: + # magiskinit embeds preload.so + dump_bin_header(args) flag += " B_INIT=1" - flag += " B_CRT0=1" + + if "magiskboot" in args.target: + flag += " B_BOOT=1" if flag: - dump_bin_header(args) + flag += " B_CRT0=1" run_ndk_build(flag) if clean: diff --git a/native/build.gradle.kts b/native/build.gradle.kts index 10fc01934..47e1c78df 100644 --- a/native/build.gradle.kts +++ b/native/build.gradle.kts @@ -22,7 +22,8 @@ android { ndkBuild { // Pass arguments to ndk-build. arguments( - "B_MAGISK=1", "B_INIT=1", "B_BOOT=1", "B_TEST=1", "B_POLICY=1", "B_PRELOAD=1", "B_PROP=1" + "B_MAGISK=1", "B_INIT=1", "B_BOOT=1", "B_POLICY=1", + "B_PRELOAD=1", "B_PROP=1", "B_CRT0=1" ) } } diff --git a/native/src/Android.mk b/native/src/Android.mk index 889794e73..88fa86686 100644 --- a/native/src/Android.mk +++ b/native/src/Android.mk @@ -109,6 +109,12 @@ LOCAL_SRC_FILES := \ LOCAL_LDFLAGS := -static -T src/lto_fix.lds +ifdef B_CRT0 +LOCAL_STATIC_LIBRARIES += crt0 +LOCAL_CFLAGS += -DUSE_MUSL_PRINTF +LOCAL_LDFLAGS := -lm -Wl,--wrap=qsort +endif + include $(BUILD_EXECUTABLE) endif diff --git a/native/src/base/files.cpp b/native/src/base/files.cpp index d3a85aa08..95181618d 100644 --- a/native/src/base/files.cpp +++ b/native/src/base/files.cpp @@ -75,12 +75,8 @@ void file_readline(bool trim, FILE *fp, const function &fn) { } void file_readline(bool trim, const char *file, const function &fn) { - int fd = xopen(file, O_RDONLY | O_CLOEXEC); - if (fd >= 0) { - auto fp = fdopen(fd, "re"); - file_readline(trim, fp, fn); - fclose(fp); - } + if (auto fp = open_file(file, "re")) + file_readline(trim, fp.get(), fn); } void file_readline(const char *file, const function &fn) { @@ -101,12 +97,8 @@ void parse_prop_file(FILE *fp, const function &f } void parse_prop_file(const char *file, const function &fn) { - int fd = xopen(file, O_RDONLY | O_CLOEXEC); - if (fd >= 0) { - auto fp = fdopen(fd, "re"); - parse_prop_file(fp, fn); - fclose(fp); - } + if (auto fp = open_file(file, "re")) + parse_prop_file(fp.get(), fn); } std::vector parse_mount_info(const char *pid) { diff --git a/native/src/base/misc.cpp b/native/src/base/misc.cpp index 7cf725345..d17707737 100644 --- a/native/src/base/misc.cpp +++ b/native/src/base/misc.cpp @@ -290,3 +290,37 @@ const char *rust::Utf8CStr::data() const { size_t rust::Utf8CStr::length() const { return cxx$utf8str$len(this); } + +#define elm(i) (p + (i * size)) + +// An alternative qsort implementation. Only used when linking with crt0 +extern "C" +void __wrap_qsort(void *ptr, size_t count, size_t size, int (*comp)(const void*, const void*)) { + // Create the index array + uint8_t *p = (uint8_t *) ptr; + vector v(count); + std::iota(v.begin(), v.end(), 0); + + // Sort the index array + std::sort(v.begin(), v.end(), [=](int a, int b) { + return comp(elm(a), elm(b)) < 0; + }); + + // Reorganize the array with index array + void *t = malloc(size); + for (int i = 0; i < count; ++i) { + if (v[i] != i) { + memcpy(t, elm(i), size); + int j = i; + int k; + while (i != (k = v[j])) { + memcpy(elm(j), elm(k), size); + v[j] = j; + j = k; + } + memcpy(elm(j), t, size); + v[j] = j; + } + } + free(t); +} diff --git a/native/src/boot/main.cpp b/native/src/boot/main.cpp index 782ca2cf9..81ffdd97b 100644 --- a/native/src/boot/main.cpp +++ b/native/src/boot/main.cpp @@ -6,6 +6,11 @@ using namespace std; +#ifdef USE_MUSL_PRINTF +// Switch to use the musl vfprintf +__asm__(".global vfprintf \n vfprintf = musl_vfprintf"); +#endif + static void print_formats() { for (int fmt = GZIP; fmt < LZOP; ++fmt) { fprintf(stderr, "%s ", fmt2name[(format_t) fmt]); diff --git a/native/src/external/crt0 b/native/src/external/crt0 index 9790b7ee4..f800c65e1 160000 --- a/native/src/external/crt0 +++ b/native/src/external/crt0 @@ -1 +1 @@ -Subproject commit 9790b7ee48d3c396c94ef69e164004f50a1f5587 +Subproject commit f800c65e1c088240c8336a0a5f0d9346dfea0697 diff --git a/native/src/sepolicy/policydb.cpp b/native/src/sepolicy/policydb.cpp index 20211054b..c23b387c2 100644 --- a/native/src/sepolicy/policydb.cpp +++ b/native/src/sepolicy/policydb.cpp @@ -103,8 +103,7 @@ sepolicy *sepolicy::from_file(const char *file) { policy_file_t pf; policy_file_init(&pf); - int fd = xopen(file, O_RDONLY | O_CLOEXEC); - auto fp = make_file(fdopen(fd, "re")); + auto fp = xopen_file(file, "re"); pf.fp = fp.get(); pf.type = PF_USE_STDIO; @@ -124,7 +123,6 @@ sepolicy *sepolicy::compile_split() { cil_db_t *db = nullptr; sepol_policydb_t *pdb = nullptr; FILE *f; - int fd; int policy_ver; const char *cil_file; #if MAGISK_DEBUG @@ -150,15 +148,13 @@ sepolicy *sepolicy::compile_split() { cil_set_target_platform(db, SEPOL_TARGET_SELINUX); cil_set_attrs_expand_generated(db, 1); - fd = xopen(SELINUX_VERSION, O_RDONLY | O_CLOEXEC); - f = fdopen(fd, "re"); + f = xfopen(SELINUX_VERSION, "re"); fscanf(f, "%d", &policy_ver); fclose(f); cil_set_policy_version(db, policy_ver); // Get mapping version - fd = xopen(VEND_POLICY_DIR "plat_sepolicy_vers.txt", O_RDONLY | O_CLOEXEC); - f = fdopen(fd, "re"); + f = xfopen(VEND_POLICY_DIR "plat_sepolicy_vers.txt", "re"); fscanf(f, "%s", plat_ver); fclose(f);