From 268ca7a60c1f880e7c698e074baf04327173dce0 Mon Sep 17 00:00:00 2001 From: Ofek Shaked Date: Sun, 16 Jun 2024 16:04:47 +0300 Subject: [PATCH] WIP --- .github/workflows/release.yml | 2 + Makefile | 6 ++ scripts/macos_rpathify.sh | 149 ++++++++++++++++++++++++++++++++++ 3 files changed, 157 insertions(+) create mode 100755 scripts/macos_rpathify.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d2b8299..2a10ef5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,6 +24,8 @@ jobs: tag_name: ${{ github.event.inputs.tag }} release_name: ${{ github.event.inputs.tag }} body: ${{ github.event.inputs.release_body }} + draft: true + prerelease: true outputs: upload_url: ${{ steps.create-release.outputs.upload_url }} diff --git a/Makefile b/Makefile index 57088d6..fd90e27 100644 --- a/Makefile +++ b/Makefile @@ -128,6 +128,12 @@ dist: all else \ cp wireshark/build/run/tracee-json.so* dist/workdir; \ fi + + @if [ "$(OS_NAME)" == "Darwin" ]; then \ + scripts/macos_rpathify.sh dist/workdir/tracee-json.so; \ + scripts/macos_rpathify.sh dist/workdir/tracee-event.so; \ + scripts/macos_rpathify.sh dist/workdir/tracee-network-capture.so; \ + fi @cp -r profiles dist/workdir @cp -r extcap dist/workdir diff --git a/scripts/macos_rpathify.sh b/scripts/macos_rpathify.sh new file mode 100755 index 0000000..3813636 --- /dev/null +++ b/scripts/macos_rpathify.sh @@ -0,0 +1,149 @@ + +#!/bin/bash +install_exclude_prefixes="/System/|/Library/|/usr/lib/|/usr/X11/|/opt/X11/|@executable_path" + +rpathify_file () { + local rpathify_exclude_prefixes="$install_exclude_prefixes|@rpath" + + # Fix a given executable, library, or plugin to be relocatable + if [ ! -f "$1" ]; then + return 0; + fi + + # + # OK, what type of file is this? + # + if ! filetype=$( otool -hv "$1" | grep -E MH_MAGIC | awk '{print $5}' ; exit "${PIPESTATUS[0]}" ) ; then + echo "Unable to rpathify $1 in $( pwd ): file type failed." + exit 1 + fi + + case "$filetype" in + + EXECUTE|DYLIB|BUNDLE) + # + # Executable, library, or plugin. (Plugins + # can be either DYLIB or BUNDLE; shared + # libraries are DYLIB.) + # + # For DYLIB and BUNDLE, fix the shared + # library identification. + # + if [[ "$filetype" = "DYLIB" || "$filetype" = "BUNDLE" ]]; then + echo "Changing shared library identification of $1" + base=$( echo "$1" | awk -F/ '{print $NF}' ) + # + # The library will end up in a directory in + # the rpath; this is what we should change its + # ID to. + # + to=@rpath/$base + /usr/bin/install_name_tool -id "$to" "$1" + + # + # If we're a library and we depend on something in + # @executable_path/../Frameworks, replace that with + # @rpath. + # + while read -r dep_lib ; do + base=$( echo "$dep_lib" | awk -F/ '{print $NF}' ) + to="@rpath/$base" + echo "Changing reference to $dep_lib to $to in $1" + /usr/bin/install_name_tool -change "$dep_lib" "$to" "$1" + done < <( otool -L "$1" | grep @executable_path/../Frameworks | awk '{print $1}' ) + + # + # Try to work around brotli's lack of a full path + # https://github.com/google/brotli/issues/934 + # + while read -r base ; do + to="@rpath/$base" + echo "Changing reference to $base to $to in $1" + /usr/bin/install_name_tool -change "$base" "$to" "$1" + done < <( otool -L "$1" | grep '^ libbrotli' | awk '{print $1}' ) + fi + + # + # Find our local rpaths and remove them. + # + otool -l "$1" | grep -A2 LC_RPATH \ + | awk '$1=="path" && $2 !~ /^@/ {print $2}' \ + | grep -E -v "$rpathify_exclude_prefixes" | \ + while read -r lc_rpath ; do + echo "Stripping LC_RPATH $lc_rpath from $1" + install_name_tool -delete_rpath "$lc_rpath" "$1" + done + + # + # Add -Wl,-rpath,@executable_path/../Frameworks + # to the rpath, so it'll find the bundled + # frameworks and libraries if they're referred + # to by @rpath/, rather than having a wrapper + # script tweak DYLD_LIBRARY_PATH. + # + if [[ "$filetype" = "EXECUTE" ]]; then + if [ -d ../Frameworks ] ; then + framework_path=../Frameworks + elif [ -d ../../Frameworks ] ; then + framework_path=../../Frameworks + else + echo "Unable to find relative path to Frameworks for $1 from $( pwd )" + exit 1 + fi + + echo "Adding @executable_path/$framework_path to rpath of $1" + /usr/bin/install_name_tool -add_rpath @executable_path/$framework_path "$1" + fi + + # + # Show the minimum supported version of macOS + # for each executable or library + # + if [[ "$filetype" = "EXECUTE" || "$filetype" = "DYLIB" ]] ; then + echo "Minimum macOS version for $1:" + otool -l "$1" | grep -A3 LC_VERSION_MIN_MACOSX + fi + + # + # Get the list of dynamic libraries on which this + # file depends, and select only the libraries that + # are in $LIBPREFIX, as those are the only ones + # that we'll be shipping in the app bundle; the + # other libraries are system-supplied or supplied + # as part of X11, will be expected to be on the + # system on which the bundle will be installed, + # and should be referred to by their full pathnames. + # + local libs=() + while read -r lib ; do + libs+=("$lib") + done < <( otool -L "$1" \ + | grep -F compatibility \ + | cut -d\( -f1 \ + | grep -E -v "$rpathify_exclude_prefixes" \ + | sort \ + | uniq \ + ) + + for lib in "${libs[@]}"; do + # + # Get the file name of the library. + # + base=$( echo "$lib" | awk -F/ '{print $NF}' ) + # + # The library will end up in a directory in + # the rpath; this is what we should change its + # file name to. + # + to=@rpath/$base + # + # Change the reference to that library. + # + echo "Changing reference to $lib to $to in $1" + /usr/bin/install_name_tool -change "$lib" "$to" "$1" + done + ;; + esac +} + +rpathify_file "$1" \ No newline at end of file