1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
#!/bin/sh
# sbopkglint test, must be sourced by sbopkglint (not run standalone).
# PKG, PRGNAM, VERSION, ARCH are set by sbopkglint. also the current
# directory is the root of the installed package tree.
########################################################################
# checks permissions and ownership of static libraries lib dirs.
# checks that static libraries actually *are* static libraries.
# if the package includes both a static and shared library, a note is
# triggered, suggesting removal of the static lib. this is not an error.
# TODO: this will give us file's idea of what's inside a .a archive:
# $ ar p blah.a | file -Sb -
# ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
# For 32-bit:
# ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
# Note that file needs the -S, seccomp causes file to occasionally fail
# with 'Bad system call' when working on stdin. No idea why, -S fixes it.
# 'not stripped' is *correct*, don't complain about it! actually maybe
# it should complain if it *is* stripped...?
# Armed with this knowledge, we can do the same kind of arch checks for
# static libs as we do for shared (32-bit belongs in lib, 64 in lib64,
# arch of the static lib should match package's ARCH, etc).
# Have a look at /usr/lib64/libm.a: it's a linker script. File says it's
# ASCII text.
# r0ni says aarch64 does this:
# ELF 64-bit LSB relocatable, ARM aarch64, version 1 (SYSV), not stripped
check_static_arch() {
local lib="$1"
local libarch="$2"
local libdir="$( dirname "$lib" )"
local dir="$( basename "$libdir" )" # lib or lib64
case "$libarch" in
x86) wantdir="lib" ;;
x86_64|aarch64) wantdir="lib64" ;;
esac
}
check_static_lib() {
case "$( ar p "$1" | file -Sb - )" in
empty) # empty static libs are allowed, but get a 'note'.
note "$1 is an empty static library, remove it if not needed by a dependee." ;;
LLVM*) ;; # e.g. "LLVM IR bitcode", assume OK.
ELF*x86-64*)
check_static_arch "$1" x86_64
;;
ELF*80386*)
check_static_arch "$1" x86
;;
ELF*aarch64*)
check_static_arch "$1" aarch64
;;
*) ;; # dunno, assume OK
esac
}
for libdir in lib lib64 usr/lib usr/lib64; do
if [ -d $libdir ]; then
find_warnfiles "bad static library ownership (should be root:root):" \
-L $libdir -mindepth 1 -maxdepth 1 -name '*.a' \! \( -user root -a -group root \)
find_warnfiles "bad static library permissions (should be 0644 or 0444):" \
-L $libdir -mindepth 1 -maxdepth 1 -name '*.a' \! \( -perm 444 -o -perm 644 \)
find $libdir -mindepth 1 -maxdepth 1 -name '*.a' | while read static; do
ftype="$( file -L -b --mime-type "$static" )"
case "$ftype" in
"application/x-archive")
check_static_lib "$static" ;;
"application/x-executable")
warn "$static is an executable, not a static library." ;;
"application/x-object")
warn "$static is a shared library (.so), not a static library." ;;
"text/plain")
# TODO: check that this is a valid linker script (when I learn how). for now, ignore.
;;
*) warn "$static is not a valid static library. MIME type is '$ftype'." ;;
esac
shared=$libdir/"$( basename "$static" .a)".so
if [ -e "$shared" ]; then
shname="$( basename "$shared" )"
stname="$( basename "$static" )"
note "$libdir has both $shname and $stname; unless it's needed by a dependee, consider removing $stname"
fi
done
fi
done
|