moved dependency on pyelftools into scoped function where it's used to reduce the number of dependencies required overall

kernel-mode
Anton Lydike 3 years ago
parent 0c96a87dcb
commit 3d4d36bfe4

@ -1,9 +1,6 @@
from dataclasses import dataclass from dataclasses import dataclass
from typing import List, Dict, Tuple from typing import List, Dict, Tuple
from elftools.elf.elffile import ELFFile
from elftools.elf.sections import Section, SymbolTableSection
from .Exceptions import * from .Exceptions import *
from ..Exceptions import RiscemuBaseException from ..Exceptions import RiscemuBaseException
from ..Executable import MemoryFlags, LoadedMemorySection from ..Executable import MemoryFlags, LoadedMemorySection
@ -12,6 +9,9 @@ from ..helpers import FMT_PARSE, FMT_NONE, FMT_GREEN, FMT_BOLD
FMT_ELF = FMT_GREEN + FMT_BOLD FMT_ELF = FMT_GREEN + FMT_BOLD
if typing.TYPE_CHECKING:
from elftools.elf.elffile import ELFFile
from elftools.elf.sections import Section, SymbolTableSection
# This requires pyelftools package! # This requires pyelftools package!
@ -29,11 +29,18 @@ class ElfExecutable:
self.sections_by_name = dict() self.sections_by_name = dict()
self.symbols = dict() self.symbols = dict()
try:
from elftools.elf.elffile import ELFFile
from elftools.elf.sections import Section, SymbolTableSection
with open(name, 'rb') as f: with open(name, 'rb') as f:
print(FMT_ELF + "[ElfLoader] Loading elf executable from: {}".format(name) + FMT_NONE) print(FMT_ELF + "[ElfLoader] Loading elf executable from: {}".format(name) + FMT_NONE)
self._read_elf(ELFFile(f)) self._read_elf(ELFFile(f))
except ImportError as e:
print(FMT_PARSE + "[ElfLoader] Cannot load elf files without PyElfTools package! You can install them using pip install pyelftools!" + FMT_NONE)
raise e
def _read_elf(self, elf: ELFFile): def _read_elf(self, elf: 'ELFFile'):
if not elf.header.e_machine == 'EM_RISCV': if not elf.header.e_machine == 'EM_RISCV':
raise InvalidElfException("Not a RISC-V elf file!") raise InvalidElfException("Not a RISC-V elf file!")
if not elf.header.e_ident.EI_CLASS == 'ELFCLASS32': if not elf.header.e_ident.EI_CLASS == 'ELFCLASS32':
@ -41,6 +48,7 @@ class ElfExecutable:
self.run_ptr = elf.header.e_entry self.run_ptr = elf.header.e_entry
from elftools.elf.sections import SymbolTableSection
for sec in elf.iter_sections(): for sec in elf.iter_sections():
if isinstance(sec, SymbolTableSection): if isinstance(sec, SymbolTableSection):
self._parse_symtab(sec) self._parse_symtab(sec)
@ -51,7 +59,7 @@ class ElfExecutable:
self.add_sec(self._lms_from_elf_sec(sec, 'kernel')) self.add_sec(self._lms_from_elf_sec(sec, 'kernel'))
def _lms_from_elf_sec(self, sec: Section, owner: str): def _lms_from_elf_sec(self, sec: 'Section', owner: str):
is_code = sec.name in ('.text',) is_code = sec.name in ('.text',)
data = bytearray(sec.data()) data = bytearray(sec.data())
flags = MemoryFlags(is_code, is_code) flags = MemoryFlags(is_code, is_code)
@ -65,7 +73,7 @@ class ElfExecutable:
owner owner
) )
def _parse_symtab(self, symtab: SymbolTableSection): def _parse_symtab(self, symtab: 'SymbolTableSection'):
self.symbols = { self.symbols = {
sym.name: sym.entry.st_value for sym in symtab.iter_symbols() if sym.name sym.name: sym.entry.st_value for sym in symtab.iter_symbols() if sym.name
} }

Loading…
Cancel
Save