summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoss Burton <ross.burton@intel.com>2016-03-24 15:43:47 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-03-25 10:28:03 +0000
commit96813445e6618fd8442600d81e53c448310b6e8b (patch)
treedb807c79e27a669558e14daf2c1bd2026cf7b46a
parent9840bfbe7d860bdb7ad9ac444a82f95510d48c2d (diff)
downloadopenembedded-core-contrib-96813445e6618fd8442600d81e53c448310b6e8b.tar.gz
openembedded-core-contrib-96813445e6618fd8442600d81e53c448310b6e8b.tar.bz2
openembedded-core-contrib-96813445e6618fd8442600d81e53c448310b6e8b.zip
lib/oe/qa: add method to check if static or dynamic linked
It's useful to know if a binary is statically or dynamically linked, so add a method to determine this. Signed-off-by: Ross Burton <ross.burton@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/lib/oe/qa.py44
1 files changed, 39 insertions, 5 deletions
diff --git a/meta/lib/oe/qa.py b/meta/lib/oe/qa.py
index 4efa21fd80..3cfeee737b 100644
--- a/meta/lib/oe/qa.py
+++ b/meta/lib/oe/qa.py
@@ -1,3 +1,5 @@
+import os, struct
+
class NotELFFileError(Exception):
pass
@@ -10,6 +12,8 @@ class ELFFile:
EI_OSABI = 7
EI_ABIVERSION = 8
+ E_MACHINE = 0x12
+
# possible values for EI_CLASS
ELFCLASSNONE = 0
ELFCLASS32 = 1
@@ -23,6 +27,8 @@ class ELFFile:
ELFDATA2LSB = 1
ELFDATA2MSB = 2
+ PT_INTERP = 3
+
def my_assert(self, expectation, result):
if not expectation == result:
#print "'%x','%x' %s" % (ord(expectation), ord(result), self.name)
@@ -38,9 +44,12 @@ class ELFFile:
raise NotELFFileError("%s is not a normal file" % self.name)
self.file = file(self.name, "r")
- self.data = self.file.read(ELFFile.EI_NIDENT+4)
+ # Read 4k which should cover most of the headers we're after
+ self.data = self.file.read(4096)
+
+ if len(self.data) < ELFFile.EI_NIDENT + 4:
+ raise NotELFFileError("%s is not an ELF" % self.name)
- self.my_assert(len(self.data), ELFFile.EI_NIDENT+4)
self.my_assert(self.data[0], chr(0x7f) )
self.my_assert(self.data[1], 'E')
self.my_assert(self.data[2], 'L')
@@ -86,14 +95,33 @@ class ELFFile:
def isBigEndian(self):
return self.sex == ">"
+ def getShort(self, offset):
+ return struct.unpack_from(self.sex+"H", self.data, offset)[0]
+
+ def getWord(self, offset):
+ return struct.unpack_from(self.sex+"i", self.data, offset)[0]
+
+ def isDynamic(self):
+ """
+ Return True if there is a .interp segment (therefore dynamically
+ linked), otherwise False (statically linked).
+ """
+ offset = self.getWord(self.bits == 32 and 0x1C or 0x20)
+ size = self.getShort(self.bits == 32 and 0x2A or 0x36)
+ count = self.getShort(self.bits == 32 and 0x2C or 0x38)
+
+ for i in range(0, count):
+ p_type = self.getWord(offset + i * size)
+ if p_type == ELFFile.PT_INTERP:
+ return True
+ return False
+
def machine(self):
"""
We know the sex stored in self.sex and we
know the position
"""
- import struct
- (a,) = struct.unpack(self.sex+"H", self.data[18:20])
- return a
+ return self.getShort(ELFFile.E_MACHINE)
def run_objdump(self, cmd, d):
import bb.process
@@ -115,3 +143,9 @@ class ELFFile:
except Exception as e:
bb.note("%s %s %s failed: %s" % (objdump, cmd, self.name, e))
return ""
+
+if __name__ == "__main__":
+ import sys
+ elf = ELFFile(sys.argv[1])
+ elf.open()
+ print elf.isDynamic()