2222# bin/ptoas - The actual ptoas binary
2323# lib/*.so* - Required shared library dependencies
2424
25- set -e
25+ set -euo pipefail
2626
2727if [ $# -lt 1 ]; then
2828 echo " Usage: $0 <output_directory>" >&2
@@ -39,7 +39,7 @@ for var in LLVM_BUILD_DIR PTO_INSTALL_DIR PTO_SOURCE_DIR; do
3939 fi
4040done
4141
42- export LD_LIBRARY_PATH=" ${LLVM_BUILD_DIR} /lib:${PTO_INSTALL_DIR} /lib:${LD_LIBRARY_PATH} "
42+ export LD_LIBRARY_PATH=" ${LLVM_BUILD_DIR} /lib:${PTO_INSTALL_DIR} /lib:${LD_LIBRARY_PATH:- } "
4343
4444PTOAS_BIN=" ${PTO_SOURCE_DIR} /build/tools/ptoas/ptoas"
4545PTOAS_DEPS_DIR=" ${PTOAS_DIST_DIR} /lib"
@@ -49,12 +49,82 @@ if [ ! -f "$PTOAS_BIN" ]; then
4949 exit 1
5050fi
5151
52+ remove_rpath () {
53+ local path=" $1 "
54+ if ! has_rpath " $path " ; then
55+ return
56+ fi
57+ if command -v patchelf > /dev/null 2>&1 ; then
58+ patchelf --remove-rpath " $path "
59+ fi
60+ if has_rpath " $path " && command -v chrpath > /dev/null 2>&1 ; then
61+ chrpath -d " $path "
62+ fi
63+ if has_rpath " $path " ; then
64+ echo " Error: failed to scrub RPATH/RUNPATH from ${path} " >&2
65+ exit 1
66+ fi
67+ }
68+
69+ strip_symbols () {
70+ local path=" $1 "
71+ strip --strip-unneeded " $path "
72+ }
73+
74+ has_rpath () {
75+ local path=" $1 "
76+ if command -v patchelf > /dev/null 2>&1 ; then
77+ local rpath_value
78+ rpath_value=" $( patchelf --print-rpath " $path " 2> /dev/null || true) "
79+ [[ -n " $rpath_value " ]]
80+ return
81+ fi
82+ readelf -d " $path " 2> /dev/null | grep -Eq ' (RPATH|RUNPATH)'
83+ }
84+
85+ assert_relro () {
86+ local path=" $1 "
87+ if ! readelf -l " $path " 2> /dev/null | grep -q ' GNU_RELRO' ; then
88+ echo " WARN: RELRO segment missing in ${path} " >&2
89+ return
90+ fi
91+ if ! readelf -d " $path " 2> /dev/null | grep -Eq ' (BIND_NOW|FLAGS.*NOW|FLAGS_1.*NOW)' ; then
92+ echo " WARN: NOW binding missing in ${path} " >&2
93+ fi
94+ }
95+
96+ assert_no_symtab () {
97+ local path=" $1 "
98+ if readelf -S " $path " 2> /dev/null | grep -Eq ' [[:space:]]\\.symtab[[:space:]]' ; then
99+ echo " Error: symbol table still present in ${path} " >&2
100+ exit 1
101+ fi
102+ }
103+
104+ assert_no_rpath () {
105+ local path=" $1 "
106+ if has_rpath " $path " ; then
107+ echo " Error: runtime search path still present in ${path} " >&2
108+ exit 1
109+ fi
110+ }
111+
112+ harden_elf () {
113+ local path=" $1 "
114+ remove_rpath " $path "
115+ strip_symbols " $path "
116+ assert_relro " $path "
117+ assert_no_symtab " $path "
118+ assert_no_rpath " $path "
119+ }
120+
52121# Create output directories
53122mkdir -p " ${PTOAS_DIST_DIR} /bin" " ${PTOAS_DEPS_DIR} "
54123
55124# Copy ptoas binary
56125echo " Copying ptoas binary..."
57126cp " $PTOAS_BIN " " ${PTOAS_DIST_DIR} /bin/"
127+ harden_elf " ${PTOAS_DIST_DIR} /bin/ptoas"
58128
59129# Collect *.so dependencies (transitive closure under /llvm-workspace)
60130echo " Collecting shared library dependencies..."
@@ -64,7 +134,8 @@ copy_so() {
64134 local name
65135 name=$( basename " $f " )
66136 [[ -f " ${PTOAS_DEPS_DIR} /${name} " ]] && return 0
67- cp -n " $f " " ${PTOAS_DEPS_DIR} /" 2> /dev/null || true
137+ cp -L -n " $f " " ${PTOAS_DEPS_DIR} /" 2> /dev/null || true
138+ harden_elf " ${PTOAS_DEPS_DIR} /${name} "
68139 while read -r res; do
69140 copy_so " $res "
70141 done < <( ldd " $f " 2> /dev/null | awk ' /=> \/llvm-workspace\// {print $3}' )
@@ -74,6 +145,10 @@ while read -r res; do
74145 copy_so " $res "
75146done < <( ldd " $PTOAS_BIN " 2> /dev/null | awk ' /=> \/llvm-workspace\// {print $3}' )
76147
148+ while read -r packaged; do
149+ harden_elf " $packaged "
150+ done < <( find " ${PTOAS_DIST_DIR} /bin" " ${PTOAS_DEPS_DIR} " -type f | sort)
151+
77152# Create wrapper script
78153echo " Creating wrapper script..."
79154cat > " ${PTOAS_DIST_DIR} /ptoas" << 'WRAPPER_EOF '
0 commit comments