41 lines
1.9 KiB
Bash
Executable File
41 lines
1.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# readelf is authoritative: host ldd alone cannot identify a foreign dynamic ELF.
|
|
source "$(dirname -- "${BASH_SOURCE[0]}")/lib.sh"
|
|
[[ $# == 3 ]] || die 'Usage: tools/verify-elf FILE {aarch64|x86_64} {static|glibc}'
|
|
elf=$1
|
|
arch=$2
|
|
mode=$3
|
|
need readelf
|
|
need file
|
|
[[ -f $elf ]] || die "Missing ELF: $elf"
|
|
case $arch in
|
|
aarch64) machine=AArch64 ;;
|
|
x86_64) machine='Advanced Micro Devices X86-64' ;;
|
|
*) die "Unsupported architecture: $arch" ;;
|
|
esac
|
|
header=$(readelf -hW "$elf")
|
|
segments=$(readelf -lW "$elf")
|
|
dynamic=$(readelf -dW "$elf")
|
|
versions=$(readelf -VW "$elf")
|
|
grep -Eq 'Class:[[:space:]]+ELF64' <<<"$header" || die 'Expected ELF64'
|
|
grep -Eq 'Data:.*little endian' <<<"$header" || die 'Expected little endian ELF'
|
|
grep -Eq "Machine:[[:space:]]+$machine$" <<<"$header" || die "Expected $arch ELF: $elf"
|
|
grep -Eq 'Type:[[:space:]]+(EXEC|DYN)' <<<"$header" || die 'Expected executable ELF'
|
|
description=$(file -Lb "$elf")
|
|
case $mode in
|
|
static)
|
|
! grep -q 'INTERP' <<<"$segments" || die "Dynamic interpreter found: $elf"
|
|
! grep -q '(NEEDED)' <<<"$dynamic" || die "Shared library dependency found: $elf"
|
|
! grep -q 'GLIBC_' <<<"$versions" || die "glibc symbol dependency found: $elf"
|
|
grep -Eq 'statically linked|static-pie linked' <<<"$description" || die "file did not identify static linkage: $description"
|
|
;;
|
|
glibc)
|
|
[[ $arch == aarch64 ]] || die 'glibc package verification currently requires aarch64'
|
|
grep -q '/lib/ld-linux-aarch64.so.1' <<<"$segments" || die 'Expected aarch64 glibc loader'
|
|
grep -Eq '\(NEEDED\).*\[libc\.so\.6\]' <<<"$dynamic" || die 'Expected glibc dependency'
|
|
! grep -q 'musl' <<<"$segments$dynamic" || die 'Unexpected musl package ABI'
|
|
;;
|
|
*) die "Unsupported linkage mode: $mode" ;;
|
|
esac
|
|
printf '%s: %s\nPASS: %s %s ELF\n' "$elf" "$description" "$arch" "$mode"
|