2
1

check-host-rpath 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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)/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. is_elf "${file}" || continue
  17. elf_needs_rpath "${file}" "${hostdir}" || continue
  18. check_elf_has_rpath "${file}" "${hostdir}" && continue
  19. if [ ${ret} -eq 0 ]; then
  20. ret=1
  21. printf "***\n"
  22. printf "*** ERROR: package %s installs executables without proper RPATH:\n" "${pkg}"
  23. fi
  24. printf "*** %s\n" "${file}"
  25. done < <( find "${hostdir}"/{bin,sbin} -type f 2>/dev/null )
  26. return ${ret}
  27. }
  28. is_elf() {
  29. local f="${1}"
  30. readelf -l "${f}" 2>/dev/null \
  31. |grep -E 'Requesting program interpreter:' >/dev/null 2>&1
  32. }
  33. elf_needs_rpath() {
  34. local file="${1}"
  35. local hostdir="${2}"
  36. local lib
  37. while read lib; do
  38. [ -e "${hostdir}/lib/${lib}" ] && return 0
  39. done < <( readelf -d "${file}" \
  40. |sed -r -e '/^.* \(NEEDED\) .*Shared library: \[(.+)\]$/!d;' \
  41. -e 's//\1/;' \
  42. )
  43. return 1
  44. }
  45. check_elf_has_rpath() {
  46. local file="${1}"
  47. local hostdir="${2}"
  48. local rpath dir
  49. while read rpath; do
  50. for dir in ${rpath//:/ }; do
  51. # Remove duplicate and trailing '/' for proper match
  52. dir="$( sed -r -e 's:/+:/:g; s:/$::;' <<<"${dir}" )"
  53. [ "${dir}" = "${hostdir}/lib" -o "${dir}" = "\$ORIGIN/../lib" ] && return 0
  54. done
  55. done < <( readelf -d "${file}" \
  56. |sed -r -e '/.* \(R(UN)?PATH\) +Library r(un)?path: \[(.+)\]$/!d' \
  57. -e 's//\3/;' \
  58. )
  59. return 1
  60. }
  61. main "${@}"