From 661931aa98c820f5ed40953af9b53484c0a59be0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 12 Apr 2022 17:01:33 +0200 Subject: [PATCH] objc_namespace: Update parsing logic to account for otool changes The textual output of otool in recent Xcode releases has changed. We now look for OBJC_CLASS_RO/OBJC_METACLASS_RO rather than class_ro_t. Pick-to: 6.2 6.3 5.15 Change-Id: I86192e91e55d8deb7e5c6790b327855fc0f7e594 Reviewed-by: Alexandru Croitor --- mkspecs/features/data/mac/objc_namespace.sh | 40 +++++++++++++-------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/mkspecs/features/data/mac/objc_namespace.sh b/mkspecs/features/data/mac/objc_namespace.sh index ceff2df324..a8f20ee221 100755 --- a/mkspecs/features/data/mac/objc_namespace.sh +++ b/mkspecs/features/data/mac/objc_namespace.sh @@ -115,20 +115,25 @@ read_32bit_value() { inspect_binary() { inspect_mode="$1" - echo -n "🔎 Inspecting binary '$target', " + echo "🔎 Inspecting binary '$target'..." if [ ! -f "$target" ]; then - echo "target does not exist!" + echo " đŸ’Ĩ Target does not exist!" exit 1 fi read -a mach_header <<< "$(otool -h "$target" -v | tail -n 1)" if [ "${mach_header[1]}" != "X86_64" ]; then - echo "binary is not 64-bit, only 64-bit binaries are supported!" + echo " đŸ’Ĩ Binary is not 64-bit, only 64-bit binaries are supported!" exit 1 fi classnames_section="__objc_classname" classnames=$(otool -v -s __TEXT $classnames_section "$target" | tail -n +3) + if [ -z "$classnames" ]; then + echo " ℹī¸ No Objective-C classes found in binary" + return 1 + fi + while read -a classname; do address=$(sanitize_address ${classname[0]}) name=${classname[1]} @@ -140,19 +145,23 @@ inspect_binary() { extra_classnames_file="$(mktemp -t ${classnames_section}_additions).S" if [ "$inspect_mode" == "inject_classnames" ]; then - echo "class names have not been namespaced, adding suffix '$suffix'..." + echo " ℹī¸ Class names have not been namespaced, adding suffix '$suffix'..." printf ".section __TEXT,$classnames_section,cstring_literals,no_dead_strip\n" > $extra_classnames_file elif [ "$inspect_mode" == "patch_classes" ]; then - echo "found namespaced class names, updating class entries..." + echo " ℹī¸ Found namespaced class names, updating class entries..." + fi + + classes=$(otool -o -v "$target" | grep "OBJC_CLASS_RO\|OBJC_METACLASS_RO") + if [ -z "$classes" ]; then + echo " đŸ’Ĩ Failed to read class entries from binary" + exit 1 fi - classes=$(otool -o -v "$target" | grep class_ro_t) while read -a class; do address="$(sanitize_address ${class[1]})" - class_flags="0x$(read_32bit_value $address)" if [ -z "$class_flags" ]; then - echo " đŸ’Ĩ failed to read class flags for class at $address" + echo " đŸ’Ĩ Failed to read class flags for class at $address" continue fi @@ -161,13 +170,13 @@ inspect_binary() { name_offset=$(($address + 24)) classname_address="0x$(read_32bit_value $name_offset)" if [ -z "$classname_address" ]; then - echo " đŸ’Ĩ failed to read class name address for class at $address" + echo " đŸ’Ĩ Failed to read class name address for class at $address" continue fi classname=$(get_entry address_to_classname $classname_address) if [ -z "$classname" ]; then - echo " đŸ’Ĩ failed to resolve class name for address '$classname_address'" + echo " đŸ’Ĩ Failed to resolve class name for address '$classname_address'" continue fi @@ -177,7 +186,7 @@ inspect_binary() { else class_type="class" fi - echo " đŸšŊ skipping excluded $class_type '$classname'" + echo " đŸšŊ Skipping excluded $class_type '$classname'" continue fi @@ -188,13 +197,13 @@ inspect_binary() { continue fi - echo " 💉 injecting $classnames_section entry '$newclassname' for '$classname'" + echo " 💉 Injecting $classnames_section entry '$newclassname' for '$classname'" printf ".asciz \"$newclassname\"\n" >> $extra_classnames_file elif [ "$inspect_mode" == "patch_classes" ]; then newclassname_address=$(get_entry classname_to_address ${newclassname}) if [ -z "$newclassname_address" ]; then - echo " đŸ’Ĩ failed to resolve class name address for class '$newclassname'" + echo " đŸ’Ĩ Failed to resolve class name address for class '$newclassname'" continue fi @@ -204,7 +213,7 @@ inspect_binary() { class_type="class" fi - echo " 🔨 patching class_ro_t at $address ($class_type) from $classname_address ($classname) to $newclassname_address ($newclassname)" + echo " 🔨 Patching class_ro_t at $address ($class_type) from $classname_address ($classname) to $newclassname_address ($newclassname)" echo ${newclassname_address: -8} | rev | dd conv=swab 2>/dev/null | xxd -p -r -seek $name_offset -l 4 - "$target" fi done <<< "$classes" @@ -214,6 +223,9 @@ echo "🔩 Linking binary using '$original_ld'..." link_binary inspect_binary inject_classnames +if [ $? -ne 0 ]; then + exit +fi echo "🔩 Re-linking binary with extra __objc_classname section..." link_binary $extra_classnames_file