summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorPhil Blundell <philb@gnu.org>2012-10-01 18:29:23 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2012-10-18 12:13:49 +0100
commitf8c90bce73647f11658edcd2dda9a3c3bfd8b274 (patch)
treeeb762cdab09f992b82582505037f9f6164488f96 /meta
parent96b8d721e94e5c7fd226600f4cae2463f0f55760 (diff)
downloadpoky-f8c90bce73647f11658edcd2dda9a3c3bfd8b274.tar.gz
insane: Rationalise phdrs-based QA checks
Various different QA checks are based on essentially the same data from the ELF program headers. Calling objdump to extract it repeatedly is inefficient, particularly if the shell is involved. Instead, let's cache the output from objdump inside the qa.elf object and allow it to be reused by multiple tests. Also, using objdump instead of scanelf to check for bad RPATHs (in the same way that the useless-rpaths check was doing already) allows the dependency on pax-utils-native to be dropped. (From OE-Core rev: bf19eeb9f65e91bf2b5d89e7c0b099c55d7c15ff) Signed-off-by: Phil Blundell <philb@gnu.org> Signed-off-by: Saul Wold <sgw@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
-rw-r--r--meta/classes/insane.bbclass41
-rw-r--r--meta/lib/oe/qa.py17
2 files changed, 35 insertions, 23 deletions
diff --git a/meta/classes/insane.bbclass b/meta/classes/insane.bbclass
index 5757ed398b..2b4841933c 100644
--- a/meta/classes/insane.bbclass
+++ b/meta/classes/insane.bbclass
@@ -17,13 +17,8 @@
17# files under exec_prefix 17# files under exec_prefix
18 18
19 19
20#
21# We need to have the scanelf utility as soon as
22# possible and this is contained within the pax-utils-native.
23# The package.bbclass can help us here.
24#
25inherit package 20inherit package
26PACKAGE_DEPENDS += "pax-utils-native ${QADEPENDS}" 21PACKAGE_DEPENDS += "${QADEPENDS}"
27PACKAGEFUNCS += " do_package_qa " 22PACKAGEFUNCS += " do_package_qa "
28 23
29# unsafe-references-in-binaries requires prelink-rtld from 24# unsafe-references-in-binaries requires prelink-rtld from
@@ -162,21 +157,23 @@ def package_qa_check_rpath(file,name, d, elf, messages):
162 if not elf: 157 if not elf:
163 return 158 return
164 159
165 scanelf = os.path.join(d.getVar('STAGING_BINDIR_NATIVE',True),'scanelf')
166 bad_dirs = [d.getVar('TMPDIR', True) + "/work", d.getVar('STAGING_DIR_TARGET', True)] 160 bad_dirs = [d.getVar('TMPDIR', True) + "/work", d.getVar('STAGING_DIR_TARGET', True)]
167 bad_dir_test = d.getVar('TMPDIR', True) 161 bad_dir_test = d.getVar('TMPDIR', True)
168 if not os.path.exists(scanelf):
169 bb.fatal("Can not check RPATH, scanelf (part of pax-utils-native) not found")
170 162
171 if not bad_dirs[0] in d.getVar('WORKDIR', True): 163 if not bad_dirs[0] in d.getVar('WORKDIR', True):
172 bb.fatal("This class assumed that WORKDIR is ${TMPDIR}/work... Not doing any check") 164 bb.fatal("This class assumed that WORKDIR is ${TMPDIR}/work... Not doing any check")
173 165
174 output = os.popen("%s -B -F%%r#F '%s'" % (scanelf,file)) 166 phdrs = elf.run_objdump("-p", d)
175 txt = output.readline().split() 167
176 for line in txt: 168 import re
177 for dir in bad_dirs: 169 rpath_re = re.compile("\s+RPATH\s+(.*)")
178 if dir in line: 170 for line in phdrs.split("\n"):
179 messages.append("package %s contains bad RPATH %s in file %s" % (name, line, file)) 171 m = rpath_re.match(line)
172 if m:
173 rpath = m.group(1)
174 for dir in bad_dirs:
175 if dir in rpath:
176 messages.append("package %s contains bad RPATH %s in file %s" % (name, rpath, file))
180 177
181QAPATHTEST[useless-rpaths] = "package_qa_check_useless_rpaths" 178QAPATHTEST[useless-rpaths] = "package_qa_check_useless_rpaths"
182def package_qa_check_useless_rpaths(file, name, d, elf, messages): 179def package_qa_check_useless_rpaths(file, name, d, elf, messages):
@@ -189,15 +186,14 @@ def package_qa_check_useless_rpaths(file, name, d, elf, messages):
189 if not elf: 186 if not elf:
190 return 187 return
191 188
192 objdump = d.getVar('OBJDUMP', True)
193 env_path = d.getVar('PATH', True)
194
195 libdir = d.getVar("libdir", True) 189 libdir = d.getVar("libdir", True)
196 base_libdir = d.getVar("base_libdir", True) 190 base_libdir = d.getVar("base_libdir", True)
197 191
192 phdrs = elf.run_objdump("-p", d)
193
198 import re 194 import re
199 rpath_re = re.compile("\s+RPATH\s+(.*)") 195 rpath_re = re.compile("\s+RPATH\s+(.*)")
200 for line in os.popen("LC_ALL=C PATH=%s %s -p '%s' 2> /dev/null" % (env_path, objdump, file), "r"): 196 for line in phdrs.split("\n"):
201 m = rpath_re.match(line) 197 m = rpath_re.match(line)
202 if m: 198 if m:
203 rpath = m.group(1) 199 rpath = m.group(1)
@@ -458,14 +454,13 @@ def package_qa_hash_style(path, name, d, elf, messages):
458 if not gnu_hash: 454 if not gnu_hash:
459 return 455 return
460 456
461 objdump = d.getVar('OBJDUMP', True)
462 env_path = d.getVar('PATH', True)
463
464 sane = False 457 sane = False
465 has_syms = False 458 has_syms = False
466 459
460 phdrs = elf.run_objdump("-p", d)
461
467 # If this binary has symbols, we expect it to have GNU_HASH too. 462 # If this binary has symbols, we expect it to have GNU_HASH too.
468 for line in os.popen("LC_ALL=C PATH=%s %s -p '%s' 2> /dev/null" % (env_path, objdump, path), "r"): 463 for line in phdrs.split("\n"):
469 if "SYMTAB" in line: 464 if "SYMTAB" in line:
470 has_syms = True 465 has_syms = True
471 if "GNU_HASH" in line: 466 if "GNU_HASH" in line:
diff --git a/meta/lib/oe/qa.py b/meta/lib/oe/qa.py
index d3800128ed..9e5ab587b7 100644
--- a/meta/lib/oe/qa.py
+++ b/meta/lib/oe/qa.py
@@ -28,6 +28,7 @@ class ELFFile:
28 def __init__(self, name, bits = 0): 28 def __init__(self, name, bits = 0):
29 self.name = name 29 self.name = name
30 self.bits = bits 30 self.bits = bits
31 self.objdump_output = {}
31 32
32 def open(self): 33 def open(self):
33 self.file = file(self.name, "r") 34 self.file = file(self.name, "r")
@@ -87,3 +88,19 @@ class ELFFile:
87 import struct 88 import struct
88 (a,) = struct.unpack(self.sex+"H", self.data[18:20]) 89 (a,) = struct.unpack(self.sex+"H", self.data[18:20])
89 return a 90 return a
91
92 def run_objdump(self, cmd, d):
93 import bb.process
94 import sys
95
96 if self.objdump_output.has_key(cmd):
97 return self.objdump_output[cmd]
98
99 objdump = d.getVar('OBJDUMP', True)
100 staging_dir = d.getVar('STAGING_BINDIR_TOOLCHAIN', True)
101
102 env = os.environ
103 env["LC_ALL"] = "C"
104
105 self.objdump_output[cmd] = bb.process.run([ os.path.join(staging_dir, objdump), cmd, self.name ], env=env, shell=False)[0]
106 return self.objdump_output[cmd]