summaryrefslogtreecommitdiffstats
path: root/meta/classes/insane.bbclass
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@linux.intel.com>2010-07-08 10:23:17 +0100
committerRichard Purdie <rpurdie@linux.intel.com>2010-07-08 10:24:15 +0100
commitb44d32ef41eff9a0a1e36865e29ad223c33d8a1e (patch)
tree78bb654d85c8cc20c711ce40a8ee63a3f47667bf /meta/classes/insane.bbclass
parent2e04ea87541479fee6dcbdd5a587f98a86428de6 (diff)
downloadpoky-b44d32ef41eff9a0a1e36865e29ad223c33d8a1e.tar.gz
insane.bbclass: Portions of code were not running, fix this and sync with OE.dev. Also add tests for bad sysroot rpaths in binaries
Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'meta/classes/insane.bbclass')
-rw-r--r--meta/classes/insane.bbclass157
1 files changed, 120 insertions, 37 deletions
diff --git a/meta/classes/insane.bbclass b/meta/classes/insane.bbclass
index 230a1be752..a04542e208 100644
--- a/meta/classes/insane.bbclass
+++ b/meta/classes/insane.bbclass
@@ -31,6 +31,9 @@ PACKAGEFUNCS += " do_package_qa "
31# TARGET_OS TARGET_ARCH MACHINE, OSABI, ABIVERSION, Little Endian, 32bit? 31# TARGET_OS TARGET_ARCH MACHINE, OSABI, ABIVERSION, Little Endian, 32bit?
32def package_qa_get_machine_dict(): 32def package_qa_get_machine_dict():
33 return { 33 return {
34 "darwin9" : {
35 "arm" : (40, 0, 0, True, True),
36 },
34 "linux" : { 37 "linux" : {
35 "arm" : (40, 97, 0, True, True), 38 "arm" : (40, 97, 0, True, True),
36 "armeb": (40, 97, 0, False, True), 39 "armeb": (40, 97, 0, False, True),
@@ -58,8 +61,12 @@ def package_qa_get_machine_dict():
58 "i486": ( 3, 0, 0, True, True), 61 "i486": ( 3, 0, 0, True, True),
59 "i586": ( 3, 0, 0, True, True), 62 "i586": ( 3, 0, 0, True, True),
60 "i686": ( 3, 0, 0, True, True), 63 "i686": ( 3, 0, 0, True, True),
64 "x86_64": ( 62, 0, 0, True, False),
65 "mips": ( 8, 0, 0, False, True),
61 "mipsel": ( 8, 0, 0, True, True), 66 "mipsel": ( 8, 0, 0, True, True),
62 "avr32": (6317, 0, 0, False, True), 67 "avr32": (6317, 0, 0, False, True),
68 "sh4": (42, 0, 0, True, True),
69
63 }, 70 },
64 "uclinux-uclibc" : { 71 "uclinux-uclibc" : {
65 "bfin": ( 106, 0, 0, True, True), 72 "bfin": ( 106, 0, 0, True, True),
@@ -72,9 +79,16 @@ def package_qa_get_machine_dict():
72 "arm" : (40, 0, 0, True, True), 79 "arm" : (40, 0, 0, True, True),
73 "armeb" : (40, 0, 0, False, True), 80 "armeb" : (40, 0, 0, False, True),
74 }, 81 },
82 "linux-gnuspe" : {
83 "powerpc": (20, 0, 0, False, True),
84 },
85 "linux-uclibcspe" : {
86 "powerpc": (20, 0, 0, False, True),
87 },
75 88
76 } 89 }
77 90
91
78# Known Error classes 92# Known Error classes
79# 0 - non dev contains .so 93# 0 - non dev contains .so
80# 1 - package contains a dangerous RPATH 94# 1 - package contains a dangerous RPATH
@@ -85,6 +99,8 @@ def package_qa_get_machine_dict():
85# 6 - .pc contains reference to /usr/include or workdir 99# 6 - .pc contains reference to /usr/include or workdir
86# 7 - the desktop file is not valid 100# 7 - the desktop file is not valid
87# 8 - .la contains reference to the workdir 101# 8 - .la contains reference to the workdir
102# 9 - LDFLAGS ignored
103# 10 - Build paths in binaries
88 104
89def package_qa_clean_path(path,d): 105def package_qa_clean_path(path,d):
90 """ Remove the common prefix from the path. In this case it is the TMPDIR""" 106 """ Remove the common prefix from the path. In this case it is the TMPDIR"""
@@ -113,6 +129,7 @@ def package_qa_write_error(error_class, name, path, d):
113 "evil hides inside the .pc", 129 "evil hides inside the .pc",
114 "the desktop file is not valid", 130 "the desktop file is not valid",
115 ".la contains reference to the workdir", 131 ".la contains reference to the workdir",
132 "LDFLAGS ignored",
116 "package contains reference to tmpdir paths", 133 "package contains reference to tmpdir paths",
117 ] 134 ]
118 135
@@ -141,69 +158,84 @@ def package_qa_handle_error(error_class, error_msg, name, path, d):
141 158
142 return not fatal 159 return not fatal
143 160
144def package_qa_check_rpath(file,name,d): 161def package_qa_check_rpath(file,name,d, elf):
145 """ 162 """
146 Check for dangerous RPATHs 163 Check for dangerous RPATHs
147 """ 164 """
165 if not elf:
166 return True
167
148 sane = True 168 sane = True
149 scanelf = os.path.join(bb.data.getVar('STAGING_BINDIR_NATIVE',d,True),'scanelf') 169 scanelf = os.path.join(bb.data.getVar('STAGING_BINDIR_NATIVE',d,True),'scanelf')
150 bad_dir = bb.data.getVar('TMPDIR', d, True) + "/work" 170 bad_dirs = [bb.data.getVar('TMPDIR', d, True) + "/work", bb.data.getVar('STAGING_DIR_TARGET', d, True)]
151 bad_dir_test = bb.data.getVar('TMPDIR', d, True) 171 bad_dir_test = bb.data.getVar('TMPDIR', d, True)
152 if not os.path.exists(scanelf): 172 if not os.path.exists(scanelf):
153 bb.fatal("Can not check RPATH, scanelf (part of pax-utils-native) not found") 173 bb.fatal("Can not check RPATH, scanelf (part of pax-utils-native) not found")
154 174
155 if not bad_dir in bb.data.getVar('WORKDIR', d, True): 175 if not bad_dirs[0] in bb.data.getVar('WORKDIR', d, True):
156 bb.fatal("This class assumed that WORKDIR is ${TMPDIR}/work... Not doing any check") 176 bb.fatal("This class assumed that WORKDIR is ${TMPDIR}/work... Not doing any check")
157 177
158 output = os.popen("%s -B -F%%r#F '%s'" % (scanelf,file)) 178 output = os.popen("%s -B -F%%r#F '%s'" % (scanelf,file))
159 txt = output.readline().split() 179 txt = output.readline().split()
160 for line in txt: 180 for line in txt:
161 if bad_dir in line: 181 for dir in bad_dirs:
162 error_msg = "package %s contains bad RPATH %s in file %s" % (name, line, file) 182 if dir in line:
163 sane = package_qa_handle_error(1, error_msg, name, file, d) 183 error_msg = "package %s contains bad RPATH %s in file %s" % (name, line, file)
184 sane = sane + package_qa_handle_error(1, error_msg, name, file, d)
164 185
165 return sane 186 return sane
166 187
167def package_qa_check_devdbg(path, name,d): 188def package_qa_check_dev(path, name,d, elf):
168 """ 189 """
169 Check for debug remains inside the binary or 190 Check for ".so" library symlinks in non-dev packages
170 non dev packages containing
171 """ 191 """
172 192
173 sane = True 193 sane = True
174 194
175 if not "-dev" in name: 195 if not name.endswith("-dev") and path.endswith(".so") and os.path.islink(path):
176 if path[-3:] == ".so" and os.path.islink(path): 196 error_msg = "non -dev package contains symlink .so: %s path '%s'" % \
177 error_msg = "non -dev package contains symlink .so: %s path '%s'" % \ 197 (name, package_qa_clean_path(path,d))
178 (name, package_qa_clean_path(path,d)) 198 sane = package_qa_handle_error(0, error_msg, name, path, d)
179 sane = package_qa_handle_error(0, error_msg, name, path, d) 199
200 return sane
201
202def package_qa_check_dbg(path, name,d, elf):
203 """
204 Check for ".debug" files or directories outside of the dbg package
205 """
206
207 sane = True
180 208
181 if not "-dbg" in name: 209 if not "-dbg" in name:
182 if '.debug' in path: 210 if '.debug' in path.split(os.path.sep):
183 error_msg = "non debug package contains .debug directory: %s path %s" % \ 211 error_msg = "non debug package contains .debug directory: %s path %s" % \
184 (name, package_qa_clean_path(path,d)) 212 (name, package_qa_clean_path(path,d))
185 sane = package_qa_handle_error(3, error_msg, name, path, d) 213 sane = package_qa_handle_error(3, error_msg, name, path, d)
186 214
187 return sane 215 return sane
188 216
189def package_qa_check_perm(path,name,d): 217def package_qa_check_perm(path,name,d, elf):
190 """ 218 """
191 Check the permission of files 219 Check the permission of files
192 """ 220 """
193 sane = True 221 sane = True
194 return sane 222 return sane
195 223
196def package_qa_check_arch(path,name,d): 224def package_qa_check_arch(path,name,d, elf):
197 """ 225 """
198 Check if archs are compatible 226 Check if archs are compatible
199 """ 227 """
228 if not elf:
229 return True
230
200 sane = True 231 sane = True
201 target_os = bb.data.getVar('TARGET_OS', d, True) 232 target_os = bb.data.getVar('TARGET_OS', d, True)
202 target_arch = bb.data.getVar('TARGET_ARCH', d, True) 233 target_arch = bb.data.getVar('TARGET_ARCH', d, True)
203 234
204 # FIXME: Cross package confuse this check, so just skip them 235 # FIXME: Cross package confuse this check, so just skip them
205 if bb.data.inherits_class('cross', d) or bb.data.inherits_class('nativesdk', d) or bb.data.inherits_class('cross-canadian', d): 236 for s in ['cross', 'nativesdk', 'cross-canadian']:
206 return True 237 if bb.data.inherits_class(s, d):
238 return True
207 239
208 # avoid following links to /usr/bin (e.g. on udev builds) 240 # avoid following links to /usr/bin (e.g. on udev builds)
209 # we will check the files pointed to anyway... 241 # we will check the files pointed to anyway...
@@ -213,11 +245,6 @@ def package_qa_check_arch(path,name,d):
213 #if this will throw an exception, then fix the dict above 245 #if this will throw an exception, then fix the dict above
214 (machine, osabi, abiversion, littleendian, bits32) \ 246 (machine, osabi, abiversion, littleendian, bits32) \
215 = package_qa_get_machine_dict()[target_os][target_arch] 247 = package_qa_get_machine_dict()[target_os][target_arch]
216 elf = package_qa_get_elf(path, bits32)
217 try:
218 elf.open()
219 except:
220 return True
221 248
222 # Check the architecture and endiannes of the binary 249 # Check the architecture and endiannes of the binary
223 if not machine == elf.machine(): 250 if not machine == elf.machine():
@@ -231,7 +258,7 @@ def package_qa_check_arch(path,name,d):
231 258
232 return sane 259 return sane
233 260
234def package_qa_check_desktop(path, name, d): 261def package_qa_check_desktop(path, name, d, elf):
235 """ 262 """
236 Run all desktop files through desktop-file-validate. 263 Run all desktop files through desktop-file-validate.
237 """ 264 """
@@ -245,7 +272,48 @@ def package_qa_check_desktop(path, name, d):
245 272
246 return sane 273 return sane
247 274
248def package_qa_check_buildpaths(path, name, d): 275def package_qa_hash_style(path, name, d, elf):
276 """
277 Check if the binary has the right hash style...
278 """
279
280 if not elf:
281 return True
282
283 if os.path.islink(path):
284 return True
285
286 gnu_hash = "--hash-style=gnu" in bb.data.getVar('LDFLAGS', d, True)
287 if not gnu_hash:
288 gnu_hash = "--hash-style=both" in bb.data.getVar('LDFLAGS', d, True)
289 if not gnu_hash:
290 return True
291
292 objdump = bb.data.getVar('OBJDUMP', d, True)
293 env_path = bb.data.getVar('PATH', d, True)
294
295 sane = True
296 elf = False
297 # A bit hacky. We do not know if path is an elf binary or not
298 # we will search for 'NEEDED' or 'INIT' as this should be printed...
299 # and come before the HASH section (guess!!!) and works on split out
300 # debug symbols too
301 for line in os.popen("LC_ALL=C PATH=%s %s -p '%s' 2> /dev/null" % (env_path, objdump, path), "r"):
302 if "NEEDED" in line or "INIT" in line:
303 sane = False
304 elf = True
305 if "GNU_HASH" in line:
306 sane = True
307 if "[mips32]" in line or "[mips64]" in line:
308 sane = True
309
310 if elf and not sane:
311 error_msg = "No GNU_HASH in the elf binary: '%s'" % path
312 return package_qa_handle_error(9, error_msg, name, path, d)
313
314 return True
315
316def package_qa_check_buildpaths(path, name, d, elf):
249 """ 317 """
250 Check for build paths inside target files and error if not found in the whitelist 318 Check for build paths inside target files and error if not found in the whitelist
251 """ 319 """
@@ -263,7 +331,7 @@ def package_qa_check_buildpaths(path, name, d):
263 file_content = open(path).read() 331 file_content = open(path).read()
264 if tmpdir in file_content: 332 if tmpdir in file_content:
265 error_msg = "File %s in package contained reference to tmpdir" % package_qa_clean_path(path,d) 333 error_msg = "File %s in package contained reference to tmpdir" % package_qa_clean_path(path,d)
266 sane = package_qa_handle_error(9, error_msg, name, path, d) 334 sane = package_qa_handle_error(10, error_msg, name, path, d)
267 return sane 335 return sane
268 336
269def package_qa_check_license(workdir, d): 337def package_qa_check_license(workdir, d):
@@ -356,7 +424,7 @@ def package_qa_check_staged(path,d):
356 for root, dirs, files in os.walk(path): 424 for root, dirs, files in os.walk(path):
357 for file in files: 425 for file in files:
358 path = os.path.join(root,file) 426 path = os.path.join(root,file)
359 if file[-2:] == "la": 427 if file.endswith(".la"):
360 file_content = open(path).read() 428 file_content = open(path).read()
361 # Don't check installed status for native/cross packages 429 # Don't check installed status for native/cross packages
362 if not bb.data.inherits_class("native", d) and not bb.data.inherits_class("cross", d): 430 if not bb.data.inherits_class("native", d) and not bb.data.inherits_class("cross", d):
@@ -366,7 +434,7 @@ def package_qa_check_staged(path,d):
366 if workdir in file_content: 434 if workdir in file_content:
367 error_msg = "%s failed sanity test (workdir) in path %s" % (file,root) 435 error_msg = "%s failed sanity test (workdir) in path %s" % (file,root)
368 sane = package_qa_handle_error(8, error_msg, "staging", path, d) 436 sane = package_qa_handle_error(8, error_msg, "staging", path, d)
369 elif file[-2:] == "pc": 437 elif file.endswith(".pc"):
370 file_content = open(path).read() 438 file_content = open(path).read()
371 if pkgconfigcheck in file_content: 439 if pkgconfigcheck in file_content:
372 error_msg = "%s failed sanity test (tmpdir) in path %s" % (file,root) 440 error_msg = "%s failed sanity test (tmpdir) in path %s" % (file,root)
@@ -376,24 +444,36 @@ def package_qa_check_staged(path,d):
376 444
377# Walk over all files in a directory and call func 445# Walk over all files in a directory and call func
378def package_qa_walk(path, funcs, package,d): 446def package_qa_walk(path, funcs, package,d):
379 sane = True 447 import oe.qa
380 448
449 #if this will throw an exception, then fix the dict above
450 target_os = bb.data.getVar('TARGET_OS', d, True)
451 target_arch = bb.data.getVar('TARGET_ARCH', d, True)
452 (machine, osabi, abiversion, littleendian, bits32) \
453 = package_qa_get_machine_dict()[target_os][target_arch]
454
455 sane = True
381 for root, dirs, files in os.walk(path): 456 for root, dirs, files in os.walk(path):
382 for file in files: 457 for file in files:
383 path = os.path.join(root,file) 458 path = os.path.join(root,file)
459 elf = oe.qa.ELFFile(path, bits32)
460 try:
461 elf.open()
462 except:
463 elf = None
384 for func in funcs: 464 for func in funcs:
385 if not func(path, package,d): 465 if not func(path, package,d, elf):
386 sane = False 466 sane = False
387 467
388 return sane 468 return sane
389 469
390def package_qa_check_rdepends(pkg, workdir, d): 470def package_qa_check_rdepends(pkg, pkgdest, d):
391 sane = True 471 sane = True
392 if not "-dbg" in pkg and not "task-" in pkg and not "-image" in pkg: 472 if not "-dbg" in pkg and not "task-" in pkg and not "-image" in pkg:
393 # Copied from package_ipk.bbclass 473 # Copied from package_ipk.bbclass
394 # boiler plate to update the data 474 # boiler plate to update the data
395 localdata = bb.data.createCopy(d) 475 localdata = bb.data.createCopy(d)
396 root = "%s/install/%s" % (workdir, pkg) 476 root = "%s/%s" % (pkgdest, pkg)
397 477
398 bb.data.setVar('ROOT', '', localdata) 478 bb.data.setVar('ROOT', '', localdata)
399 bb.data.setVar('ROOT_%s' % pkg, root, localdata) 479 bb.data.setVar('ROOT_%s' % pkg, root, localdata)
@@ -425,6 +505,7 @@ def package_qa_check_rdepends(pkg, workdir, d):
425# The PACKAGE FUNC to scan each package 505# The PACKAGE FUNC to scan each package
426python do_package_qa () { 506python do_package_qa () {
427 bb.note("DO PACKAGE QA") 507 bb.note("DO PACKAGE QA")
508 pkgdest = bb.data.getVar('PKGDEST', d, True)
428 workdir = bb.data.getVar('WORKDIR', d, True) 509 workdir = bb.data.getVar('WORKDIR', d, True)
429 packages = bb.data.getVar('PACKAGES',d, True) 510 packages = bb.data.getVar('PACKAGES',d, True)
430 511
@@ -432,9 +513,11 @@ python do_package_qa () {
432 if not packages: 513 if not packages:
433 return 514 return
434 515
435 checks = [package_qa_check_rpath, package_qa_check_devdbg, 516 checks = [package_qa_check_rpath, package_qa_check_dev,
436 package_qa_check_perm, package_qa_check_arch, 517 package_qa_check_perm, package_qa_check_arch,
437 package_qa_check_desktop, package_qa_check_buildpaths] 518 package_qa_check_desktop,
519 package_qa_check_dbg]
520 # package_qa_check_buildpaths, package_qa_hash_style
438 walk_sane = True 521 walk_sane = True
439 rdepends_sane = True 522 rdepends_sane = True
440 for package in packages.split(): 523 for package in packages.split():
@@ -443,10 +526,10 @@ python do_package_qa () {
443 continue 526 continue
444 527
445 bb.note("Checking Package: %s" % package) 528 bb.note("Checking Package: %s" % package)
446 path = "%s/install/%s" % (workdir, package) 529 path = "%s/%s" % (pkgdest, package)
447 if not package_qa_walk(path, checks, package, d): 530 if not package_qa_walk(path, checks, package, d):
448 walk_sane = False 531 walk_sane = False
449 if not package_qa_check_rdepends(package, workdir, d): 532 if not package_qa_check_rdepends(package, pkgdest, d):
450 rdepends_sane = False 533 rdepends_sane = False
451 534
452 535