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 /meta/lib/oe/qa.py | |
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>
Diffstat (limited to 'meta/lib/oe/qa.py')
-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() | ||