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 <alexandru.croitor@qt.io>
This commit is contained in:
parent
8ae20c975a
commit
661931aa98
@ -115,20 +115,25 @@ read_32bit_value() {
|
|||||||
inspect_binary() {
|
inspect_binary() {
|
||||||
inspect_mode="$1"
|
inspect_mode="$1"
|
||||||
|
|
||||||
echo -n "🔎 Inspecting binary '$target', "
|
echo "🔎 Inspecting binary '$target'..."
|
||||||
if [ ! -f "$target" ]; then
|
if [ ! -f "$target" ]; then
|
||||||
echo "target does not exist!"
|
echo " 💥 Target does not exist!"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
read -a mach_header <<< "$(otool -h "$target" -v | tail -n 1)"
|
read -a mach_header <<< "$(otool -h "$target" -v | tail -n 1)"
|
||||||
if [ "${mach_header[1]}" != "X86_64" ]; then
|
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
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
classnames_section="__objc_classname"
|
classnames_section="__objc_classname"
|
||||||
classnames=$(otool -v -s __TEXT $classnames_section "$target" | tail -n +3)
|
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
|
while read -a classname; do
|
||||||
address=$(sanitize_address ${classname[0]})
|
address=$(sanitize_address ${classname[0]})
|
||||||
name=${classname[1]}
|
name=${classname[1]}
|
||||||
@ -140,19 +145,23 @@ inspect_binary() {
|
|||||||
extra_classnames_file="$(mktemp -t ${classnames_section}_additions).S"
|
extra_classnames_file="$(mktemp -t ${classnames_section}_additions).S"
|
||||||
|
|
||||||
if [ "$inspect_mode" == "inject_classnames" ]; then
|
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
|
printf ".section __TEXT,$classnames_section,cstring_literals,no_dead_strip\n" > $extra_classnames_file
|
||||||
elif [ "$inspect_mode" == "patch_classes" ]; then
|
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
|
fi
|
||||||
|
|
||||||
classes=$(otool -o -v "$target" | grep class_ro_t)
|
|
||||||
while read -a class; do
|
while read -a class; do
|
||||||
address="$(sanitize_address ${class[1]})"
|
address="$(sanitize_address ${class[1]})"
|
||||||
|
|
||||||
class_flags="0x$(read_32bit_value $address)"
|
class_flags="0x$(read_32bit_value $address)"
|
||||||
if [ -z "$class_flags" ]; then
|
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
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -161,13 +170,13 @@ inspect_binary() {
|
|||||||
name_offset=$(($address + 24))
|
name_offset=$(($address + 24))
|
||||||
classname_address="0x$(read_32bit_value $name_offset)"
|
classname_address="0x$(read_32bit_value $name_offset)"
|
||||||
if [ -z "$classname_address" ]; then
|
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
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
classname=$(get_entry address_to_classname $classname_address)
|
classname=$(get_entry address_to_classname $classname_address)
|
||||||
if [ -z "$classname" ]; then
|
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
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -177,7 +186,7 @@ inspect_binary() {
|
|||||||
else
|
else
|
||||||
class_type="class"
|
class_type="class"
|
||||||
fi
|
fi
|
||||||
echo " 🚽 skipping excluded $class_type '$classname'"
|
echo " 🚽 Skipping excluded $class_type '$classname'"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -188,13 +197,13 @@ inspect_binary() {
|
|||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo " 💉 injecting $classnames_section entry '$newclassname' for '$classname'"
|
echo " 💉 Injecting $classnames_section entry '$newclassname' for '$classname'"
|
||||||
printf ".asciz \"$newclassname\"\n" >> $extra_classnames_file
|
printf ".asciz \"$newclassname\"\n" >> $extra_classnames_file
|
||||||
|
|
||||||
elif [ "$inspect_mode" == "patch_classes" ]; then
|
elif [ "$inspect_mode" == "patch_classes" ]; then
|
||||||
newclassname_address=$(get_entry classname_to_address ${newclassname})
|
newclassname_address=$(get_entry classname_to_address ${newclassname})
|
||||||
if [ -z "$newclassname_address" ]; then
|
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
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -204,7 +213,7 @@ inspect_binary() {
|
|||||||
class_type="class"
|
class_type="class"
|
||||||
fi
|
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"
|
echo ${newclassname_address: -8} | rev | dd conv=swab 2>/dev/null | xxd -p -r -seek $name_offset -l 4 - "$target"
|
||||||
fi
|
fi
|
||||||
done <<< "$classes"
|
done <<< "$classes"
|
||||||
@ -214,6 +223,9 @@ echo "🔩 Linking binary using '$original_ld'..."
|
|||||||
link_binary
|
link_binary
|
||||||
|
|
||||||
inspect_binary inject_classnames
|
inspect_binary inject_classnames
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
echo "🔩 Re-linking binary with extra __objc_classname section..."
|
echo "🔩 Re-linking binary with extra __objc_classname section..."
|
||||||
link_binary $extra_classnames_file
|
link_binary $extra_classnames_file
|
||||||
|
Loading…
Reference in New Issue
Block a user