Files
Giacomo Vercesi 942cf50735 python: create python wheels
Package revng's python code in two wheels: `revng` and `revng_internal`.
The revng wheel contains the
`revng.{pipeline_description,model,tupletree}` modules, while the
`revng_internal` one everything under `revng.internal`.
2023-12-12 14:52:22 +01:00

82 lines
2.1 KiB
Python

#
# This file is distributed under the MIT License. See LICENSE.md for details.
#
from pathlib import Path
from typing import List, Union
from elftools.elf.dynamic import DynamicSegment
from elftools.elf.elffile import ELFFile
def get_elf_needed(path: str) -> List[str]:
with open(path, "rb") as elf_file:
segments = [
segment
for segment in ELFFile(elf_file).iter_segments()
if isinstance(segment, DynamicSegment)
]
if len(segments) != 1:
return []
needed = [
to_string(tag.needed)
for tag in segments[0].iter_tags()
if tag.entry.d_tag == "DT_NEEDED"
]
elf_runpath: List[str] = [
tag.runpath for tag in segments[0].iter_tags() if tag.entry.d_tag == "DT_RUNPATH"
]
assert len(elf_runpath) < 2
if not elf_runpath:
return needed
runpaths = [
runpath.replace("$ORIGIN", str(Path(path).parent))
for runpath in elf_runpath[0].split(":")
]
absolute_needed = []
for lib in needed:
found = False
for runpath in runpaths:
full_path = Path(runpath) / lib
if full_path.is_file():
absolute_needed.append(str(full_path.resolve()))
found = True
break
if not found:
absolute_needed.append(lib)
return absolute_needed
def is_executable(path: str) -> bool:
with open(path, "rb") as program:
return program.read(4) == b"\x7fELF"
def is_dynamic(path: str) -> bool:
with open(path, "rb") as input_file:
return (
len(
[
segment
for segment in ELFFile(input_file).iter_segments()
if segment.header.p_type == "PT_DYNAMIC"
]
)
!= 0
)
# Use in case different version of pyelftools might give str or bytes
def to_string(obj: Union[str, bytes]) -> str:
if isinstance(obj, str):
return obj
return obj.decode("utf-8")