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. (From OE-Core rev: 96813445e6618fd8442600d81e53c448310b6e8b) Signed-off-by: Ross Burton <ross.burton@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
parent
10b6037624
commit
c3c0d0ac55
|
@ -1,3 +1,5 @@
|
||||||
|
import os, struct
|
||||||
|
|
||||||
class NotELFFileError(Exception):
|
class NotELFFileError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -10,6 +12,8 @@ class ELFFile:
|
||||||
EI_OSABI = 7
|
EI_OSABI = 7
|
||||||
EI_ABIVERSION = 8
|
EI_ABIVERSION = 8
|
||||||
|
|
||||||
|
E_MACHINE = 0x12
|
||||||
|
|
||||||
# possible values for EI_CLASS
|
# possible values for EI_CLASS
|
||||||
ELFCLASSNONE = 0
|
ELFCLASSNONE = 0
|
||||||
ELFCLASS32 = 1
|
ELFCLASS32 = 1
|
||||||
|
@ -23,6 +27,8 @@ class ELFFile:
|
||||||
ELFDATA2LSB = 1
|
ELFDATA2LSB = 1
|
||||||
ELFDATA2MSB = 2
|
ELFDATA2MSB = 2
|
||||||
|
|
||||||
|
PT_INTERP = 3
|
||||||
|
|
||||||
def my_assert(self, expectation, result):
|
def my_assert(self, expectation, result):
|
||||||
if not expectation == result:
|
if not expectation == result:
|
||||||
#print "'%x','%x' %s" % (ord(expectation), ord(result), self.name)
|
#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)
|
raise NotELFFileError("%s is not a normal file" % self.name)
|
||||||
|
|
||||||
self.file = file(self.name, "r")
|
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[0], chr(0x7f) )
|
||||||
self.my_assert(self.data[1], 'E')
|
self.my_assert(self.data[1], 'E')
|
||||||
self.my_assert(self.data[2], 'L')
|
self.my_assert(self.data[2], 'L')
|
||||||
|
@ -86,14 +95,33 @@ class ELFFile:
|
||||||
def isBigEndian(self):
|
def isBigEndian(self):
|
||||||
return self.sex == ">"
|
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):
|
def machine(self):
|
||||||
"""
|
"""
|
||||||
We know the sex stored in self.sex and we
|
We know the sex stored in self.sex and we
|
||||||
know the position
|
know the position
|
||||||
"""
|
"""
|
||||||
import struct
|
return self.getShort(ELFFile.E_MACHINE)
|
||||||
(a,) = struct.unpack(self.sex+"H", self.data[18:20])
|
|
||||||
return a
|
|
||||||
|
|
||||||
def run_objdump(self, cmd, d):
|
def run_objdump(self, cmd, d):
|
||||||
import bb.process
|
import bb.process
|
||||||
|
@ -115,3 +143,9 @@ class ELFFile:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
bb.note("%s %s %s failed: %s" % (objdump, cmd, self.name, e))
|
bb.note("%s %s %s failed: %s" % (objdump, cmd, self.name, e))
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import sys
|
||||||
|
elf = ELFFile(sys.argv[1])
|
||||||
|
elf.open()
|
||||||
|
print elf.isDynamic()
|
||||||
|
|
Loading…
Reference in New Issue