diff options
Diffstat (limited to 'meta/lib/oe')
-rw-r--r-- | meta/lib/oe/qa.py | 82 |
1 files changed, 41 insertions, 41 deletions
diff --git a/meta/lib/oe/qa.py b/meta/lib/oe/qa.py index fbe719d8ec..22d76dcbcd 100644 --- a/meta/lib/oe/qa.py +++ b/meta/lib/oe/qa.py | |||
@@ -1,4 +1,4 @@ | |||
1 | import os, struct | 1 | import os, struct, mmap |
2 | 2 | ||
3 | class NotELFFileError(Exception): | 3 | class NotELFFileError(Exception): |
4 | pass | 4 | pass |
@@ -23,9 +23,9 @@ class ELFFile: | |||
23 | EV_CURRENT = 1 | 23 | EV_CURRENT = 1 |
24 | 24 | ||
25 | # possible values for EI_DATA | 25 | # possible values for EI_DATA |
26 | ELFDATANONE = 0 | 26 | EI_DATA_NONE = 0 |
27 | ELFDATA2LSB = 1 | 27 | EI_DATA_LSB = 1 |
28 | ELFDATA2MSB = 2 | 28 | EI_DATA_MSB = 2 |
29 | 29 | ||
30 | PT_INTERP = 3 | 30 | PT_INTERP = 3 |
31 | 31 | ||
@@ -34,51 +34,46 @@ class ELFFile: | |||
34 | #print "'%x','%x' %s" % (ord(expectation), ord(result), self.name) | 34 | #print "'%x','%x' %s" % (ord(expectation), ord(result), self.name) |
35 | raise NotELFFileError("%s is not an ELF" % self.name) | 35 | raise NotELFFileError("%s is not an ELF" % self.name) |
36 | 36 | ||
37 | def __init__(self, name, bits = 0): | 37 | def __init__(self, name): |
38 | self.name = name | 38 | self.name = name |
39 | self.bits = bits | ||
40 | self.objdump_output = {} | 39 | self.objdump_output = {} |
41 | 40 | ||
42 | def open(self): | 41 | # Context Manager functions to close the mmap explicitly |
43 | if not os.path.isfile(self.name): | 42 | def __enter__(self): |
44 | raise NotELFFileError("%s is not a normal file" % self.name) | 43 | return self |
44 | |||
45 | def __exit__(self, exc_type, exc_value, traceback): | ||
46 | self.data.close() | ||
45 | 47 | ||
48 | def open(self): | ||
46 | with open(self.name, "rb") as f: | 49 | with open(self.name, "rb") as f: |
47 | # Read 4k which should cover most of the headers we're after | 50 | try: |
48 | self.data = f.read(4096) | 51 | self.data = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) |
52 | except ValueError: | ||
53 | # This means the file is empty | ||
54 | raise NotELFFileError("%s is empty" % self.name) | ||
49 | 55 | ||
56 | # Check the file has the minimum number of ELF table entries | ||
50 | if len(self.data) < ELFFile.EI_NIDENT + 4: | 57 | if len(self.data) < ELFFile.EI_NIDENT + 4: |
51 | raise NotELFFileError("%s is not an ELF" % self.name) | 58 | raise NotELFFileError("%s is not an ELF" % self.name) |
52 | 59 | ||
60 | # ELF header | ||
53 | self.my_assert(self.data[0], 0x7f) | 61 | self.my_assert(self.data[0], 0x7f) |
54 | self.my_assert(self.data[1], ord('E')) | 62 | self.my_assert(self.data[1], ord('E')) |
55 | self.my_assert(self.data[2], ord('L')) | 63 | self.my_assert(self.data[2], ord('L')) |
56 | self.my_assert(self.data[3], ord('F')) | 64 | self.my_assert(self.data[3], ord('F')) |
57 | if self.bits == 0: | 65 | if self.data[ELFFile.EI_CLASS] == ELFFile.ELFCLASS32: |
58 | if self.data[ELFFile.EI_CLASS] == ELFFile.ELFCLASS32: | 66 | self.bits = 32 |
59 | self.bits = 32 | 67 | elif self.data[ELFFile.EI_CLASS] == ELFFile.ELFCLASS64: |
60 | elif self.data[ELFFile.EI_CLASS] == ELFFile.ELFCLASS64: | 68 | self.bits = 64 |
61 | self.bits = 64 | ||
62 | else: | ||
63 | # Not 32-bit or 64.. lets assert | ||
64 | raise NotELFFileError("ELF but not 32 or 64 bit.") | ||
65 | elif self.bits == 32: | ||
66 | self.my_assert(self.data[ELFFile.EI_CLASS], ELFFile.ELFCLASS32) | ||
67 | elif self.bits == 64: | ||
68 | self.my_assert(self.data[ELFFile.EI_CLASS], ELFFile.ELFCLASS64) | ||
69 | else: | 69 | else: |
70 | raise NotELFFileError("Must specify unknown, 32 or 64 bit size.") | 70 | # Not 32-bit or 64.. lets assert |
71 | raise NotELFFileError("ELF but not 32 or 64 bit.") | ||
71 | self.my_assert(self.data[ELFFile.EI_VERSION], ELFFile.EV_CURRENT) | 72 | self.my_assert(self.data[ELFFile.EI_VERSION], ELFFile.EV_CURRENT) |
72 | 73 | ||
73 | self.sex = self.data[ELFFile.EI_DATA] | 74 | self.endian = self.data[ELFFile.EI_DATA] |
74 | if self.sex == ELFFile.ELFDATANONE: | 75 | if self.endian not in (ELFFile.EI_DATA_LSB, ELFFile.EI_DATA_MSB): |
75 | raise NotELFFileError("self.sex == ELFDATANONE") | 76 | raise NotELFFileError("Unexpected EI_DATA %x" % self.endian) |
76 | elif self.sex == ELFFile.ELFDATA2LSB: | ||
77 | self.sex = "<" | ||
78 | elif self.sex == ELFFile.ELFDATA2MSB: | ||
79 | self.sex = ">" | ||
80 | else: | ||
81 | raise NotELFFileError("Unknown self.sex") | ||
82 | 77 | ||
83 | def osAbi(self): | 78 | def osAbi(self): |
84 | return self.data[ELFFile.EI_OSABI] | 79 | return self.data[ELFFile.EI_OSABI] |
@@ -90,16 +85,20 @@ class ELFFile: | |||
90 | return self.bits | 85 | return self.bits |
91 | 86 | ||
92 | def isLittleEndian(self): | 87 | def isLittleEndian(self): |
93 | return self.sex == "<" | 88 | return self.endian == ELFFile.EI_DATA_LSB |
94 | 89 | ||
95 | def isBigEndian(self): | 90 | def isBigEndian(self): |
96 | return self.sex == ">" | 91 | return self.endian == ELFFile.EI_DATA_MSB |
92 | |||
93 | def getStructEndian(self): | ||
94 | return {ELFFile.EI_DATA_LSB: "<", | ||
95 | ELFFile.EI_DATA_MSB: ">"}[self.endian] | ||
97 | 96 | ||
98 | def getShort(self, offset): | 97 | def getShort(self, offset): |
99 | return struct.unpack_from(self.sex+"H", self.data, offset)[0] | 98 | return struct.unpack_from(self.getStructEndian() + "H", self.data, offset)[0] |
100 | 99 | ||
101 | def getWord(self, offset): | 100 | def getWord(self, offset): |
102 | return struct.unpack_from(self.sex+"i", self.data, offset)[0] | 101 | return struct.unpack_from(self.getStructEndian() + "i", self.data, offset)[0] |
103 | 102 | ||
104 | def isDynamic(self): | 103 | def isDynamic(self): |
105 | """ | 104 | """ |
@@ -118,7 +117,7 @@ class ELFFile: | |||
118 | 117 | ||
119 | def machine(self): | 118 | def machine(self): |
120 | """ | 119 | """ |
121 | We know the sex stored in self.sex and we | 120 | We know the endian stored in self.endian and we |
122 | know the position | 121 | know the position |
123 | """ | 122 | """ |
124 | return self.getShort(ELFFile.E_MACHINE) | 123 | return self.getShort(ELFFile.E_MACHINE) |
@@ -166,6 +165,7 @@ def elf_machine_to_string(machine): | |||
166 | 165 | ||
167 | if __name__ == "__main__": | 166 | if __name__ == "__main__": |
168 | import sys | 167 | import sys |
169 | elf = ELFFile(sys.argv[1]) | 168 | |
170 | elf.open() | 169 | with ELFFile(sys.argv[1]) as elf: |
171 | print(elf.isDynamic()) | 170 | elf.open() |
171 | print(elf.isDynamic()) | ||