Skip to content

Commit 3ef5137

Browse files
committed
Rearrange components setup methods
1 parent b868ecd commit 3ef5137

File tree

3 files changed

+58
-34
lines changed

3 files changed

+58
-34
lines changed

qiling/core.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ def __init__(
153153
if endian is None:
154154
endian = QL_ENDIAN.EL
155155

156-
self._arch = arch_setup(archtype, endian, thumb, self)
156+
self._arch = select_arch(archtype, endian, thumb)(self)
157157

158158
self.uc = self.arch.uc
159159

@@ -173,19 +173,23 @@ def __init__(
173173
###########
174174
# Profile #
175175
###########
176-
self._profile = profile_setup(self, ostype, profile)
176+
self.log.debug(f'Profile: {profile or "default"}')
177+
self._profile = profile_setup(ostype, profile)
177178

178179
##########
179180
# Loader #
180181
##########
181-
self._loader = loader_setup(self, ostype, libcache)
182+
self._loader = select_loader(ostype, libcache)(self)
182183

183184
##############
184185
# Components #
185186
##############
186187
if not self.interpreter:
187-
self._mem = component_setup("os", "memory", self)
188-
self._os = os_setup(ostype, self)
188+
self._mem = select_component('os', 'memory')(self)
189+
self._os = select_os(ostype)(self)
190+
191+
if self.baremetal:
192+
self._hw = select_component('hw', 'hw')(self)
189193

190194
# Run the loader
191195
self.loader.run()
@@ -554,7 +558,10 @@ def run(self, begin=None, end=None, timeout=0, count=0, code=None):
554558
return self.arch.run(code)
555559

556560
# init debugger (if set)
557-
debugger = debugger_setup(self._debugger, self)
561+
debugger = select_debugger(self._debugger)
562+
563+
if debugger:
564+
debugger = debugger(self)
558565

559566
# patch binary
560567
self.do_bin_patch()

qiling/loader/mcu.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
from qiling.const import *
1111
from qiling.core import Qiling
12-
from qiling.utils import component_setup
1312
from .loader import QlLoader
1413

1514

@@ -62,8 +61,6 @@ def __init__(self, ql:Qiling):
6261
self.load_address = 0
6362
self.filetype = self.guess_filetype()
6463

65-
self.ql._hw = component_setup("hw", "hw", self.ql)
66-
6764
if self.filetype == 'elf':
6865
with open(self.ql.path, 'rb') as infile:
6966
self.elf = ELFFile(io.BytesIO(infile.read()))

qiling/utils.py

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,24 @@
1212
import importlib, os
1313

1414
from configparser import ConfigParser
15-
from typing import Any, Mapping, Optional, Tuple, Type, Union
15+
from typing import TYPE_CHECKING, Any, Callable, Mapping, Optional, Tuple, TypeVar, Union
1616

1717
from unicorn import UC_ERR_READ_UNMAPPED, UC_ERR_FETCH_UNMAPPED
1818

1919
from qiling.exception import *
2020
from qiling.const import QL_ARCH, QL_ENDIAN, QL_OS, QL_DEBUGGER
2121
from qiling.const import debugger_map, arch_map, os_map, arch_os_map
2222

23+
if TYPE_CHECKING:
24+
from qiling import Qiling
25+
from qiling.arch.arch import QlArch
26+
from qiling.debugger.debugger import QlDebugger
27+
from qiling.loader.loader import QlLoader
28+
from qiling.os.os import QlOs
29+
30+
T = TypeVar('T')
31+
QlClassInit = Callable[['Qiling'], T]
32+
2333
def catch_KeyboardInterrupt(ql, func):
2434
def wrapper(*args, **kw):
2535
try:
@@ -273,9 +283,12 @@ def ql_guess_emu_env(path: str) -> Tuple[Optional[QL_ARCH], Optional[QL_OS], Opt
273283

274284
return arch, ostype, endian
275285

286+
def select_loader(ostype: QL_OS, libcache: bool) -> QlClassInit['QlLoader']:
287+
if ostype == QL_OS.WINDOWS:
288+
kwargs = {'libcache' : libcache}
276289

277-
def loader_setup(ql, ostype: QL_OS, libcache: bool):
278-
args = [libcache] if ostype == QL_OS.WINDOWS else []
290+
else:
291+
kwargs = {}
279292

280293
module = {
281294
QL_OS.LINUX : r'elf',
@@ -295,45 +308,57 @@ def loader_setup(ql, ostype: QL_OS, libcache: bool):
295308

296309
obj = ql_get_module_function(qlloader_path, qlloader_class)
297310

298-
return obj(ql, *args)
299-
311+
return partial(obj, **kwargs)
300312

301-
def component_setup(component_type: str, component_name: str, ql):
313+
def select_component(component_type: str, component_name: str, **kwargs) -> QlClassInit[Any]:
302314
component_path = f'qiling.{component_type}.{component_name}'
303315
component_class = f'Ql{component_name.capitalize()}Manager'
304316

305317
obj = ql_get_module_function(component_path, component_class)
306318

307-
return obj(ql)
319+
return partial(obj, **kwargs)
308320

309-
310-
def debugger_setup(options: Union[str, bool], ql):
321+
def select_debugger(options: Union[str, bool]) -> Optional[QlClassInit['QlDebugger']]:
311322
if options is True:
312323
options = 'gdb'
313324

314325
if type(options) is str:
315326
objname, *args = options.split(':')
327+
dbgtype = debugger_convert(objname)
328+
329+
if dbgtype == QL_DEBUGGER.GDB:
330+
kwargs = dict(zip(('ip', 'port'), args))
331+
332+
elif dbgtype == QL_DEBUGGER.QDB:
333+
kwargs = {}
334+
335+
if 'rr' in args:
336+
kwargs['rr'] = True
337+
args.remove('rr')
316338

317-
if debugger_convert(objname) not in enum_values(QL_DEBUGGER):
339+
if args:
340+
kwargs['init_hook'] = args[0]
341+
342+
else:
318343
raise QlErrorOutput('Debugger not supported')
319344

320345
obj = ql_get_module_function(f'qiling.debugger.{objname}.{objname}', f'Ql{str.capitalize(objname)}')
321346

322-
return obj(ql, *args)
347+
return partial(obj, **kwargs)
323348

324349
return None
325350

326-
def arch_setup(archtype: QL_ARCH, endian: QL_ENDIAN, thumb: bool, ql):
351+
def select_arch(archtype: QL_ARCH, endian: QL_ENDIAN, thumb: bool) -> QlClassInit['QlArch']:
327352
# set endianess and thumb mode for arm-based archs
328353
if archtype == QL_ARCH.ARM:
329-
args = [endian, thumb]
354+
kwargs = {'endian' : endian, 'thumb' : thumb}
330355

331356
# set endianess for mips arch
332357
elif archtype == QL_ARCH.MIPS:
333-
args = [endian]
358+
kwargs = {'endian' : endian}
334359

335360
else:
336-
args = []
361+
kwargs = {}
337362

338363
module = {
339364
QL_ARCH.A8086 : r'x86',
@@ -353,8 +378,7 @@ def arch_setup(archtype: QL_ARCH, endian: QL_ENDIAN, thumb: bool, ql):
353378

354379
obj = ql_get_module_function(qlarch_path, qlarch_class)
355380

356-
return obj(ql, *args)
357-
381+
return partial(obj, **kwargs)
358382

359383
# This function is extracted from os_setup (QlOsPosix) so I put it here.
360384
def ql_syscall_mapping_function(ostype: QL_OS, archtype: QL_ARCH):
@@ -366,20 +390,16 @@ def ql_syscall_mapping_function(ostype: QL_OS, archtype: QL_ARCH):
366390

367391
return func(archtype)
368392

369-
370-
def os_setup(ostype: QL_OS, ql):
371-
qlos_name = ostype_convert_str(ostype)
393+
def select_os(ostype: QL_OS) -> QlClassInit['QlOs']:
394+
qlos_name = ostype.name
372395
qlos_path = f'qiling.os.{qlos_name.lower()}.{qlos_name.lower()}'
373396
qlos_class = f'QlOs{qlos_name.capitalize()}'
374397

375398
obj = ql_get_module_function(qlos_path, qlos_class)
376399

377-
return obj(ql)
378-
379-
380-
def profile_setup(ql, ostype: QL_OS, filename: Optional[str]):
381-
ql.log.debug(f'Profile: {filename or "default"}')
400+
return partial(obj)
382401

402+
def profile_setup(ostype: QL_OS, filename: Optional[str]):
383403
# mcu uses a yaml-based config
384404
if ostype == QL_OS.MCU:
385405
import yaml

0 commit comments

Comments
 (0)