diff options
| author | Ross Burton <ross.burton@intel.com> | 2016-03-24 15:43:47 +0000 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2016-03-26 07:34:58 +0000 |
| commit | c3c0d0ac55836d657d1a695d290a2ef2f32eb2a4 (patch) | |
| tree | 084073b00f2a0ddf6204c2c257d0e2c485aa4526 | |
| parent | 10b6037624b93a4f6fa71cfab8dee2e24d6c3565 (diff) | |
| download | poky-c3c0d0ac55836d657d1a695d290a2ef2f32eb2a4.tar.gz | |
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>
| -rw-r--r-- | meta/lib/oe/qa.py | 44 |
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 @@ | |||
| 1 | import os, struct | ||
| 2 | |||
| 1 | class NotELFFileError(Exception): | 3 | class NotELFFileError(Exception): |
| 2 | pass | 4 | pass |
| 3 | 5 | ||
| @@ -10,6 +12,8 @@ class ELFFile: | |||
| 10 | EI_OSABI = 7 | 12 | EI_OSABI = 7 |
| 11 | EI_ABIVERSION = 8 | 13 | EI_ABIVERSION = 8 |
| 12 | 14 | ||
| 15 | E_MACHINE = 0x12 | ||
| 16 | |||
| 13 | # possible values for EI_CLASS | 17 | # possible values for EI_CLASS |
| 14 | ELFCLASSNONE = 0 | 18 | ELFCLASSNONE = 0 |
| 15 | ELFCLASS32 = 1 | 19 | ELFCLASS32 = 1 |
| @@ -23,6 +27,8 @@ class ELFFile: | |||
| 23 | ELFDATA2LSB = 1 | 27 | ELFDATA2LSB = 1 |
| 24 | ELFDATA2MSB = 2 | 28 | ELFDATA2MSB = 2 |
| 25 | 29 | ||
| 30 | PT_INTERP = 3 | ||
| 31 | |||
| 26 | def my_assert(self, expectation, result): | 32 | def my_assert(self, expectation, result): |
| 27 | if not expectation == result: | 33 | if not expectation == result: |
| 28 | #print "'%x','%x' %s" % (ord(expectation), ord(result), self.name) | 34 | #print "'%x','%x' %s" % (ord(expectation), ord(result), self.name) |
| @@ -38,9 +44,12 @@ class ELFFile: | |||
| 38 | raise NotELFFileError("%s is not a normal file" % self.name) | 44 | raise NotELFFileError("%s is not a normal file" % self.name) |
| 39 | 45 | ||
| 40 | self.file = file(self.name, "r") | 46 | self.file = file(self.name, "r") |
| 41 | self.data = self.file.read(ELFFile.EI_NIDENT+4) | 47 | # Read 4k which should cover most of the headers we're after |
| 48 | self.data = self.file.read(4096) | ||
| 49 | |||
| 50 | if len(self.data) < ELFFile.EI_NIDENT + 4: | ||
| 51 | raise NotELFFileError("%s is not an ELF" % self.name) | ||
| 42 | 52 | ||
| 43 | self.my_assert(len(self.data), ELFFile.EI_NIDENT+4) | ||
| 44 | self.my_assert(self.data[0], chr(0x7f) ) | 53 | self.my_assert(self.data[0], chr(0x7f) ) |
| 45 | self.my_assert(self.data[1], 'E') | 54 | self.my_assert(self.data[1], 'E') |
| 46 | self.my_assert(self.data[2], 'L') | 55 | self.my_assert(self.data[2], 'L') |
| @@ -86,14 +95,33 @@ class ELFFile: | |||
| 86 | def isBigEndian(self): | 95 | def isBigEndian(self): |
| 87 | return self.sex == ">" | 96 | return self.sex == ">" |
| 88 | 97 | ||
| 98 | def getShort(self, offset): | ||
| 99 | return struct.unpack_from(self.sex+"H", self.data, offset)[0] | ||
| 100 | |||
| 101 | def getWord(self, offset): | ||
| 102 | return struct.unpack_from(self.sex+"i", self.data, offset)[0] | ||
| 103 | |||
| 104 | def isDynamic(self): | ||
| 105 | """ | ||
| 106 | Return True if there is a .interp segment (therefore dynamically | ||
| 107 | linked), otherwise False (statically linked). | ||
| 108 | """ | ||
| 109 | offset = self.getWord(self.bits == 32 and 0x1C or 0x20) | ||
| 110 | size = self.getShort(self.bits == 32 and 0x2A or 0x36) | ||
| 111 | count = self.getShort(self.bits == 32 and 0x2C or 0x38) | ||
| 112 | |||
| 113 | for i in range(0, count): | ||
| 114 | p_type = self.getWord(offset + i * size) | ||
| 115 | if p_type == ELFFile.PT_INTERP: | ||
| 116 | return True | ||
| 117 | return False | ||
| 118 | |||
| 89 | def machine(self): | 119 | def machine(self): |
| 90 | """ | 120 | """ |
| 91 | We know the sex stored in self.sex and we | 121 | We know the sex stored in self.sex and we |
| 92 | know the position | 122 | know the position |
| 93 | """ | 123 | """ |
| 94 | import struct | 124 | return self.getShort(ELFFile.E_MACHINE) |
| 95 | (a,) = struct.unpack(self.sex+"H", self.data[18:20]) | ||
| 96 | return a | ||
| 97 | 125 | ||
| 98 | def run_objdump(self, cmd, d): | 126 | def run_objdump(self, cmd, d): |
| 99 | import bb.process | 127 | import bb.process |
| @@ -115,3 +143,9 @@ class ELFFile: | |||
| 115 | except Exception as e: | 143 | except Exception as e: |
| 116 | bb.note("%s %s %s failed: %s" % (objdump, cmd, self.name, e)) | 144 | bb.note("%s %s %s failed: %s" % (objdump, cmd, self.name, e)) |
| 117 | return "" | 145 | return "" |
| 146 | |||
| 147 | if __name__ == "__main__": | ||
| 148 | import sys | ||
| 149 | elf = ELFFile(sys.argv[1]) | ||
| 150 | elf.open() | ||
| 151 | print elf.isDynamic() | ||
