From 60f9d69e016b11c468c98ea75ba0a60c44afbbc4 Mon Sep 17 00:00:00 2001 From: Patrick Williams Date: Wed, 17 Aug 2016 14:31:25 -0500 Subject: yocto-poky: Move to import-layers subdir We are going to import additional layers, so create a subdir to hold all of the layers that we import with git-subtree. Change-Id: I6f732153a22be8ca663035c518837e3cc5ec0799 Signed-off-by: Patrick Williams --- import-layers/yocto-poky/meta/lib/oe/qa.py | 151 +++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 import-layers/yocto-poky/meta/lib/oe/qa.py (limited to 'import-layers/yocto-poky/meta/lib/oe/qa.py') diff --git a/import-layers/yocto-poky/meta/lib/oe/qa.py b/import-layers/yocto-poky/meta/lib/oe/qa.py new file mode 100644 index 000000000..3cfeee737 --- /dev/null +++ b/import-layers/yocto-poky/meta/lib/oe/qa.py @@ -0,0 +1,151 @@ +import os, struct + +class NotELFFileError(Exception): + pass + +class ELFFile: + EI_NIDENT = 16 + + EI_CLASS = 4 + EI_DATA = 5 + EI_VERSION = 6 + EI_OSABI = 7 + EI_ABIVERSION = 8 + + E_MACHINE = 0x12 + + # possible values for EI_CLASS + ELFCLASSNONE = 0 + ELFCLASS32 = 1 + ELFCLASS64 = 2 + + # possible value for EI_VERSION + EV_CURRENT = 1 + + # possible values for EI_DATA + ELFDATANONE = 0 + 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) + raise NotELFFileError("%s is not an ELF" % self.name) + + def __init__(self, name, bits = 0): + self.name = name + self.bits = bits + self.objdump_output = {} + + def open(self): + if not os.path.isfile(self.name): + raise NotELFFileError("%s is not a normal file" % self.name) + + self.file = file(self.name, "r") + # 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(self.data[0], chr(0x7f) ) + self.my_assert(self.data[1], 'E') + self.my_assert(self.data[2], 'L') + self.my_assert(self.data[3], 'F') + if self.bits == 0: + if self.data[ELFFile.EI_CLASS] == chr(ELFFile.ELFCLASS32): + self.bits = 32 + elif self.data[ELFFile.EI_CLASS] == chr(ELFFile.ELFCLASS64): + self.bits = 64 + else: + # Not 32-bit or 64.. lets assert + raise NotELFFileError("ELF but not 32 or 64 bit.") + elif self.bits == 32: + self.my_assert(self.data[ELFFile.EI_CLASS], chr(ELFFile.ELFCLASS32)) + elif self.bits == 64: + self.my_assert(self.data[ELFFile.EI_CLASS], chr(ELFFile.ELFCLASS64)) + else: + raise NotELFFileError("Must specify unknown, 32 or 64 bit size.") + self.my_assert(self.data[ELFFile.EI_VERSION], chr(ELFFile.EV_CURRENT) ) + + self.sex = self.data[ELFFile.EI_DATA] + if self.sex == chr(ELFFile.ELFDATANONE): + raise NotELFFileError("self.sex == ELFDATANONE") + elif self.sex == chr(ELFFile.ELFDATA2LSB): + self.sex = "<" + elif self.sex == chr(ELFFile.ELFDATA2MSB): + self.sex = ">" + else: + raise NotELFFileError("Unknown self.sex") + + def osAbi(self): + return ord(self.data[ELFFile.EI_OSABI]) + + def abiVersion(self): + return ord(self.data[ELFFile.EI_ABIVERSION]) + + def abiSize(self): + return self.bits + + def isLittleEndian(self): + return self.sex == "<" + + 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 + """ + return self.getShort(ELFFile.E_MACHINE) + + def run_objdump(self, cmd, d): + import bb.process + import sys + + if cmd in self.objdump_output: + return self.objdump_output[cmd] + + objdump = d.getVar('OBJDUMP', True) + + env = os.environ.copy() + env["LC_ALL"] = "C" + env["PATH"] = d.getVar('PATH', True) + + try: + bb.note("%s %s %s" % (objdump, cmd, self.name)) + self.objdump_output[cmd] = bb.process.run([objdump, cmd, self.name], env=env, shell=False)[0] + return self.objdump_output[cmd] + 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() -- cgit v1.2.1