-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Zang Ruochen
committed
Mar 26, 2024
1 parent
52d7296
commit 53206a3
Showing
20 changed files
with
2,707 additions
and
1,143 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,24 +2,14 @@ | |
# 2.0, and the BSD License. See the LICENSE file in the root of this repository | ||
# for complete details. | ||
|
||
from .__about__ import ( | ||
__author__, | ||
__copyright__, | ||
__email__, | ||
__license__, | ||
__summary__, | ||
__title__, | ||
__uri__, | ||
__version__, | ||
) | ||
__title__ = "packaging" | ||
__summary__ = "Core utilities for Python packages" | ||
__uri__ = "https://github.com/pypa/packaging" | ||
|
||
__all__ = [ | ||
"__title__", | ||
"__summary__", | ||
"__uri__", | ||
"__version__", | ||
"__author__", | ||
"__email__", | ||
"__license__", | ||
"__copyright__", | ||
] | ||
__version__ = "24.0" | ||
|
||
__author__ = "Donald Stufft and individual contributors" | ||
__email__ = "[email protected]" | ||
|
||
__license__ = "BSD-2-Clause or Apache-2.0" | ||
__copyright__ = "2014 %s" % __author__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
""" | ||
ELF file parser. | ||
This provides a class ``ELFFile`` that parses an ELF executable in a similar | ||
interface to ``ZipFile``. Only the read interface is implemented. | ||
Based on: https://gist.github.com/lyssdod/f51579ae8d93c8657a5564aefc2ffbca | ||
ELF header: https://refspecs.linuxfoundation.org/elf/gabi4+/ch4.eheader.html | ||
""" | ||
|
||
import enum | ||
import os | ||
import struct | ||
from typing import IO, Optional, Tuple | ||
|
||
|
||
class ELFInvalid(ValueError): | ||
pass | ||
|
||
|
||
class EIClass(enum.IntEnum): | ||
C32 = 1 | ||
C64 = 2 | ||
|
||
|
||
class EIData(enum.IntEnum): | ||
Lsb = 1 | ||
Msb = 2 | ||
|
||
|
||
class EMachine(enum.IntEnum): | ||
I386 = 3 | ||
S390 = 22 | ||
Arm = 40 | ||
X8664 = 62 | ||
AArc64 = 183 | ||
|
||
|
||
class ELFFile: | ||
""" | ||
Representation of an ELF executable. | ||
""" | ||
|
||
def __init__(self, f: IO[bytes]) -> None: | ||
self._f = f | ||
|
||
try: | ||
ident = self._read("16B") | ||
except struct.error: | ||
raise ELFInvalid("unable to parse identification") | ||
magic = bytes(ident[:4]) | ||
if magic != b"\x7fELF": | ||
raise ELFInvalid(f"invalid magic: {magic!r}") | ||
|
||
self.capacity = ident[4] # Format for program header (bitness). | ||
self.encoding = ident[5] # Data structure encoding (endianness). | ||
|
||
try: | ||
# e_fmt: Format for program header. | ||
# p_fmt: Format for section header. | ||
# p_idx: Indexes to find p_type, p_offset, and p_filesz. | ||
e_fmt, self._p_fmt, self._p_idx = { | ||
(1, 1): ("<HHIIIIIHHH", "<IIIIIIII", (0, 1, 4)), # 32-bit LSB. | ||
(1, 2): (">HHIIIIIHHH", ">IIIIIIII", (0, 1, 4)), # 32-bit MSB. | ||
(2, 1): ("<HHIQQQIHHH", "<IIQQQQQQ", (0, 2, 5)), # 64-bit LSB. | ||
(2, 2): (">HHIQQQIHHH", ">IIQQQQQQ", (0, 2, 5)), # 64-bit MSB. | ||
}[(self.capacity, self.encoding)] | ||
except KeyError: | ||
raise ELFInvalid( | ||
f"unrecognized capacity ({self.capacity}) or " | ||
f"encoding ({self.encoding})" | ||
) | ||
|
||
try: | ||
( | ||
_, | ||
self.machine, # Architecture type. | ||
_, | ||
_, | ||
self._e_phoff, # Offset of program header. | ||
_, | ||
self.flags, # Processor-specific flags. | ||
_, | ||
self._e_phentsize, # Size of section. | ||
self._e_phnum, # Number of sections. | ||
) = self._read(e_fmt) | ||
except struct.error as e: | ||
raise ELFInvalid("unable to parse machine and section information") from e | ||
|
||
def _read(self, fmt: str) -> Tuple[int, ...]: | ||
return struct.unpack(fmt, self._f.read(struct.calcsize(fmt))) | ||
|
||
@property | ||
def interpreter(self) -> Optional[str]: | ||
""" | ||
The path recorded in the ``PT_INTERP`` section header. | ||
""" | ||
for index in range(self._e_phnum): | ||
self._f.seek(self._e_phoff + self._e_phentsize * index) | ||
try: | ||
data = self._read(self._p_fmt) | ||
except struct.error: | ||
continue | ||
if data[self._p_idx[0]] != 3: # Not PT_INTERP. | ||
continue | ||
self._f.seek(data[self._p_idx[1]]) | ||
return os.fsdecode(self._f.read(data[self._p_idx[2]])).strip("\0") | ||
return None |
Oops, something went wrong.