check-host-rpath 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #!/usr/bin/env bash
  2. # This script scans $(HOST_DIR)/{bin,sbin} for all ELF files, and checks
  3. # they have an RPATH to $(HOST_DIR)/usr/lib if they need libraries from
  4. # there.
  5. # Override the user's locale so we are sure we can parse the output of
  6. # readelf(1) and file(1)
  7. export LC_ALL=C
  8. main() {
  9. local pkg="${1}"
  10. local hostdir="${2}"
  11. local file ret
  12. # Remove duplicate and trailing '/' for proper match
  13. hostdir="$( sed -r -e 's:/+:/:g; s:/$::;' <<<"${hostdir}" )"
  14. ret=0
  15. while read file; do
  16. elf_needs_rpath "${file}" "${hostdir}" || continue
  17. check_elf_has_rpath "${file}" "${hostdir}" && continue
  18. if [ ${ret} -eq 0 ]; then
  19. ret=1
  20. printf "***\n"
  21. printf "*** ERROR: package %s installs executables without proper RPATH:\n" "${pkg}"
  22. fi
  23. printf "*** %s\n" "${file}"
  24. done < <( find "${hostdir}"/usr/{bin,sbin} -type f -exec file {} + 2>/dev/null \
  25. |sed -r -e '/^([^:]+):.*\<ELF\>.*\<executable\>.*/!d' \
  26. -e 's//\1/' \
  27. )
  28. return ${ret}
  29. }
  30. elf_needs_rpath() {
  31. local file="${1}"
  32. local hostdir="${2}"
  33. local lib
  34. while read lib; do
  35. [ -e "${hostdir}/usr/lib/${lib}" ] && return 0
  36. done < <( readelf -d "${file}" \
  37. |sed -r -e '/^.* \(NEEDED\) .*Shared library: \[(.+)\]$/!d;' \
  38. -e 's//\1/;' \
  39. )
  40. return 1
  41. }
  42. check_elf_has_rpath() {
  43. local file="${1}"
  44. local hostdir="${2}"
  45. local rpath dir
  46. while read rpath; do
  47. for dir in ${rpath//:/ }; do
  48. # Remove duplicate and trailing '/' for proper match
  49. dir="$( sed -r -e 's:/+:/:g; s:/$::;' <<<"${dir}" )"
  50. [ "${dir}" = "${hostdir}/usr/lib" ] && return 0
  51. done
  52. done < <( readelf -d "${file}" \
  53. |sed -r -e '/.* \(R(UN)?PATH\) +Library r(un)?path: \[(.+)\]$/!d' \
  54. -e 's//\3/;' \
  55. )
  56. return 1
  57. }
  58. main "${@}"