diff --git a/.gitattributes b/.gitattributes index 7f18b085d..eed785ce8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -12,7 +12,8 @@ # Denote all files that are truly binary and should not be modified. tools/** binary -tools/rustup_wrapper/** -binary +tools/rustup-wrapper/** -binary +tools/elf-cleaner/** -binary *.jar binary *.exe binary *.apk binary diff --git a/.gitmodules b/.gitmodules index 289d25b98..89f2f0886 100644 --- a/.gitmodules +++ b/.gitmodules @@ -25,6 +25,3 @@ [submodule "crt0"] path = native/src/external/crt0 url = https://github.com/topjohnwu/crt0.git -[submodule "termux-elf-cleaner"] - path = tools/termux-elf-cleaner - url = https://github.com/termux/termux-elf-cleaner.git diff --git a/build.py b/build.py index 461218e8e..055726b78 100755 --- a/build.py +++ b/build.py @@ -148,27 +148,16 @@ def cmd_out(cmds: list): def clean_elf(): - if is_windows: - elf_cleaner = Path("tools", "elf-cleaner.exe") - else: - elf_cleaner = Path("native", "out", "elf-cleaner") - if not elf_cleaner.exists(): - execv( - [ - "gcc", - '-DPACKAGE_NAME="termux-elf-cleaner"', - '-DPACKAGE_VERSION="2.1.1"', - '-DCOPYRIGHT="Copyright (C) 2022 Termux."', - "tools/termux-elf-cleaner/elf-cleaner.cpp", - "tools/termux-elf-cleaner/arghandling.c", - "-o", - elf_cleaner, - ] - ) - cmds = [elf_cleaner, "--api-level", "23"] + cargo_toml = Path("tools", "elf-cleaner", "Cargo.toml") + cmds = ["run", "--release", "--manifest-path", cargo_toml] + if args.verbose == 0: + cmds.append("-q") + elif args.verbose > 1: + cmds.append("--verbose") + cmds.append("--") cmds.extend(glob.glob("native/out/*/magisk")) cmds.extend(glob.glob("native/out/*/magiskpolicy")) - execv(cmds) + run_cargo(cmds) def run_ndk_build(cmds: list): @@ -484,6 +473,7 @@ def cleanup(): if "native" in targets: rm_rf(Path("native", "out")) + rm_rf(Path("tools", "elf-cleaner", "target")) if "app" in targets: header("* Cleaning app") @@ -553,8 +543,8 @@ def setup_rustup(): tgt = wrapper_dir / src.name tgt.symlink_to(f"rustup{EXE_EXT}") - # Build rustup_wrapper - wrapper_src = Path("tools", "rustup_wrapper") + # Build rustup-wrapper + wrapper_src = Path("tools", "rustup-wrapper") cargo_toml = wrapper_src / "Cargo.toml" cmds = ["build", "--release", f"--manifest-path={cargo_toml}"] if args.verbose > 1: @@ -564,7 +554,7 @@ def setup_rustup(): # Replace rustup with wrapper wrapper = wrapper_dir / (f"rustup{EXE_EXT}") wrapper.unlink(missing_ok=True) - cp(wrapper_src / "target" / "release" / (f"rustup_wrapper{EXE_EXT}"), wrapper) + cp(wrapper_src / "target" / "release" / (f"rustup-wrapper{EXE_EXT}"), wrapper) wrapper.chmod(0o755) diff --git a/tools/elf-cleaner.exe b/tools/elf-cleaner.exe deleted file mode 100755 index 5136cbd0a..000000000 Binary files a/tools/elf-cleaner.exe and /dev/null differ diff --git a/tools/elf-cleaner/.gitignore b/tools/elf-cleaner/.gitignore new file mode 100644 index 000000000..ea8c4bf7f --- /dev/null +++ b/tools/elf-cleaner/.gitignore @@ -0,0 +1 @@ +/target diff --git a/tools/elf-cleaner/Cargo.lock b/tools/elf-cleaner/Cargo.lock new file mode 100644 index 000000000..1e995843f --- /dev/null +++ b/tools/elf-cleaner/Cargo.lock @@ -0,0 +1,133 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "anyhow" +version = "1.0.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "elf-cleaner" +version = "0.0.0" +dependencies = [ + "anyhow", + "object", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "flate2" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "foldhash", +] + +[[package]] +name = "indexmap" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "miniz_oxide" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +dependencies = [ + "adler2", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "crc32fast", + "flate2", + "hashbrown", + "indexmap", + "memchr", + "ruzstd", +] + +[[package]] +name = "ruzstd" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fad02996bfc73da3e301efe90b1837be9ed8f4a462b6ed410aa35d00381de89f" +dependencies = [ + "twox-hash", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if", + "static_assertions", +] diff --git a/tools/elf-cleaner/Cargo.toml b/tools/elf-cleaner/Cargo.toml new file mode 100644 index 000000000..3115d957b --- /dev/null +++ b/tools/elf-cleaner/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "elf-cleaner" +version = "0.0.0" +edition = "2024" + +[dependencies] +object = { version = "0.36", features = ["build"] } +anyhow = "1.0" + +[profile.release] +strip = true +lto = true +codegen-units = 1 diff --git a/tools/elf-cleaner/src/main.rs b/tools/elf-cleaner/src/main.rs new file mode 100644 index 000000000..21ff21ceb --- /dev/null +++ b/tools/elf-cleaner/src/main.rs @@ -0,0 +1,85 @@ +use object::build::elf::{Builder, Dynamic, SectionData}; +use object::elf; +use std::{env, fs}; + +// Implementation adapted from https://github.com/termux/termux-elf-cleaner + +// Missing ELF constants +const DT_AARCH64_BTI_PLT: u32 = elf::DT_LOPROC + 1; +const DT_AARCH64_PAC_PLT: u32 = elf::DT_LOPROC + 3; +const DT_AARCH64_VARIANT_PCS: u32 = elf::DT_LOPROC + 5; + +const SUPPORTED_DT_FLAGS: u32 = elf::DF_1_NOW | elf::DF_1_GLOBAL; + +fn print_remove_dynamic(name: &str, path: &str) { + println!("Removing dynamic section entry {} in '{}'", name, path); +} + +fn process_elf(path: &str) -> anyhow::Result<()> { + let bytes = fs::read(path)?; + let mut elf = Builder::read(bytes.as_slice())?; + let is_aarch64 = elf.header.e_machine == elf::EM_AARCH64; + + elf.sections.iter_mut().for_each(|section| { + if let SectionData::Dynamic(entries) = &mut section.data { + // Remove unsupported entries + entries.retain(|e| { + let tag = e.tag(); + match tag { + elf::DT_RPATH => { + print_remove_dynamic("DT_RPATH", path); + return false; + } + elf::DT_RUNPATH => { + print_remove_dynamic("DT_RUNPATH", path); + return false; + } + _ => {} + } + if is_aarch64 { + match tag { + DT_AARCH64_BTI_PLT => { + print_remove_dynamic("DT_AARCH64_BTI_PLT", path); + return false; + } + DT_AARCH64_PAC_PLT => { + print_remove_dynamic("DT_AARCH64_PAC_PLT", path); + return false; + } + DT_AARCH64_VARIANT_PCS => { + print_remove_dynamic("DT_AARCH64_VARIANT_PCS", path); + return false; + } + _ => {} + } + } + true + }); + // Remove unsupported flags + for entry in entries.iter_mut() { + if let Dynamic::Integer { tag, val } = entry { + if *tag == elf::DT_FLAGS_1 { + let new_flags = *val & SUPPORTED_DT_FLAGS as u64; + if new_flags != *val { + println!( + "Replacing unsupported DT_FLAGS_1 {:#x} with {:#x} in '{}'", + *val, new_flags, path + ); + *val = new_flags; + } + break; + } + } + } + } + }); + + let mut out_bytes = Vec::new(); + elf.write(&mut out_bytes)?; + fs::write(path, &out_bytes)?; + Ok(()) +} + +fn main() -> anyhow::Result<()> { + env::args().skip(1).try_for_each(|s| process_elf(&s)) +} diff --git a/tools/rustup_wrapper/.gitignore b/tools/rustup-wrapper/.gitignore similarity index 100% rename from tools/rustup_wrapper/.gitignore rename to tools/rustup-wrapper/.gitignore diff --git a/tools/rustup_wrapper/Cargo.lock b/tools/rustup-wrapper/Cargo.lock similarity index 99% rename from tools/rustup_wrapper/Cargo.lock rename to tools/rustup-wrapper/Cargo.lock index 6943e2377..4748dc54f 100644 --- a/tools/rustup_wrapper/Cargo.lock +++ b/tools/rustup-wrapper/Cargo.lock @@ -12,7 +12,7 @@ dependencies = [ ] [[package]] -name = "rustup_wrapper" +name = "rustup-wrapper" version = "0.0.0" dependencies = [ "home", diff --git a/tools/rustup_wrapper/Cargo.toml b/tools/rustup-wrapper/Cargo.toml similarity index 74% rename from tools/rustup_wrapper/Cargo.toml rename to tools/rustup-wrapper/Cargo.toml index b52684d81..c9196f94c 100644 --- a/tools/rustup_wrapper/Cargo.toml +++ b/tools/rustup-wrapper/Cargo.toml @@ -1,7 +1,7 @@ [package] -name = "rustup_wrapper" +name = "rustup-wrapper" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] home = "0.5" diff --git a/tools/rustup_wrapper/src/main.rs b/tools/rustup-wrapper/src/main.rs similarity index 100% rename from tools/rustup_wrapper/src/main.rs rename to tools/rustup-wrapper/src/main.rs diff --git a/tools/termux-elf-cleaner b/tools/termux-elf-cleaner deleted file mode 160000 index 55b68119a..000000000 --- a/tools/termux-elf-cleaner +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 55b68119abfca84c9bff009d6505c24862610ca1