|
|
@ -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()
|
|
|
|
|
|
|
|
|
|
|
|
with open(name, 'rb') as f:
|
|
|
|
try:
|
|
|
|
print(FMT_ELF + "[ElfLoader] Loading elf executable from: {}".format(name) + FMT_NONE)
|
|
|
|
from elftools.elf.elffile import ELFFile
|
|
|
|
self._read_elf(ELFFile(f))
|
|
|
|
from elftools.elf.sections import Section, SymbolTableSection
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
with open(name, 'rb') as f:
|
|
|
|
|
|
|
|
print(FMT_ELF + "[ElfLoader] Loading elf executable from: {}".format(name) + FMT_NONE)
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|