@@ -382,7 +382,7 @@ def __init__(self, functions=None, min_calls=2, min_length=3, start=BASE_ADDRESS
382
382
else :
383
383
name = value
384
384
self .unexpanded [addr ] = name
385
- self .functions = {} # addr -> (name, end )
385
+ self .functions = {} # addr -> (name, end_address )
386
386
self .not_funcs = set ()
387
387
self .min_calls , self .min_length , self .start , self .stop = min_calls , min_length , start , stop
388
388
self .macros = macros
@@ -468,7 +468,7 @@ def analyze_func(self, rom, addr, state=None):
468
468
exit_behaved = False
469
469
end = rom .size | 0x08000000 if ins is None else ins .address
470
470
break
471
- elif ins .id == Opcode .ldr : # Mark target as WORD
471
+ elif ins .id == Opcode .ldr : # Mark load target as WORD
472
472
end = addr = ins .address + 2
473
473
target = ins .target
474
474
if target < self .stop : # TODO: Is this necessary?
@@ -559,25 +559,27 @@ def label_for(self, addr):
559
559
return name
560
560
return f'_{ addr :08X} '
561
561
562
- def dump (self , rom , path = None , config_output = None ):
563
- if config_output : # Optionally, write updated function list
562
+ def dump (self , rom , path = None , config_output = None , default_mode = BYTE ):
563
+ if config_output : # Optionally write updated function list
564
564
addr_map = {addr : (name , self .module_addrs .get (addr , None )) for addr , (name , _ ) in self .functions .items ()}
565
565
write_config (addr_map , config_output )
566
566
# Setup initial module & file
567
567
folder , module = os .path .split (path ) if path else (None , None )
568
- if DEBUG and path : # Output function range info if debugging
568
+ if DEBUG and path :
569
569
import pickle
570
+ # Output function range info if debugging
570
571
with open (os .path .join (folder , 'funcs.pickle' ), 'wb' ) as f :
571
572
pickle .dump (self .debug_ranges , f )
573
+ # Also output a linker script
572
574
fl = open ('luvdis.ld' , 'w' )
573
575
f = None if path else sys .stdout
574
576
# Setup start and end addresses
575
577
addr = self .start
576
- if type (self .stop ) is float : # End is the final address in the ROM
578
+ if type (self .stop ) is float : # End at the final address in the ROM
577
579
end = rom .size | BASE_ADDRESS
578
580
else :
579
581
end = min (rom .size , self .stop & 0xffffff ) | BASE_ADDRESS
580
- if addr not in self .module_addrs and module : # Set module of initial address to the path output
582
+ if addr not in self .module_addrs and module : # Mark the very first address as belonging to the initial module
581
583
self .module_addrs [addr ] = module
582
584
mode , flags , bytecount = BYTE , 0 , 0
583
585
# Initialize progress bar & messages
@@ -594,8 +596,8 @@ def warn(*args):
594
596
old_mode = mode
595
597
596
598
# Switch output modes
597
- if addr_flags == 0 and flags != 0 : # Switch to byte mode when address flags are zero
598
- mode = BYTE
599
+ if addr_flags == 0 and flags != 0 : # Switch to default mode when address flags are zero
600
+ mode = default_mode # By default, BYTE mode
599
601
elif addr_flags & FLAG_EXEC and not (flags & FLAG_EXEC ): # Output code
600
602
mode = THUMB
601
603
elif addr_flags & FLAG_WORD and not (flags & FLAG_WORD ) and not (addr_flags & FLAG_EXEC ): # Output words
@@ -638,7 +640,7 @@ def warn(*args):
638
640
# Switch module output
639
641
if f is not sys .stdout and addr in self .module_addrs : # Address has module info
640
642
new_module = self .module_addrs [addr ]
641
- if new_module != module or f is None : # New /first module seen
643
+ if new_module != module or f is None : # Entering new /first module
642
644
module = new_module
643
645
path = os .path .join (folder , module )
644
646
eprint (f"{ addr :08X} : module '{ path } '" )
@@ -651,12 +653,12 @@ def warn(*args):
651
653
f = open (path , 'w' , buffering = 1 )
652
654
f .write (ASM_PRELUDE )
653
655
f .write (f'.include "{ self .macros } "\n ' if self .macros else MACROS )
654
- bytecount = 0 # Reset byte bytecount
655
- if DEBUG : # Output link script if debugging
656
+ bytecount = 0 # Reset bytecount
657
+ if DEBUG : # Output linker script if debugging
656
658
fl .write (f'{ path [:- 2 ]} .o(.text);\n ' )
657
659
658
660
# Emit code or data
659
- if mode == THUMB :
661
+ if mode == THUMB : # THUMB code
660
662
offset = ins .size
661
663
if ins .id == Opcode .bl or ins .id in BRANCHES :
662
664
target = ins .target
@@ -672,7 +674,7 @@ def warn(*args):
672
674
emit = f'.2byte 0x{ i :04X} @ { ins .mnemonic } _{ target :08X} '
673
675
elif ins .id == Opcode .bx :
674
676
value = rom .read (addr , 2 )
675
- # Assembler cannot emit bx with nonzero rd, see THUMB.5 TODO: Should these be illegal?
677
+ # Assembler will not emit bx with nonzero rd, see THUMB.5 TODO: Should these be treated as illegal?
676
678
emit = f'.inst 0x{ value :04X} ' if value & 3 != 0 else str (ins )
677
679
elif ins .id == Opcode .ldr and isinstance (ins , Thumb6 ): # Convert PC-relative loads into labels
678
680
target = ins .target
@@ -700,10 +702,7 @@ def warn(*args):
700
702
value = self .label_for (value - 1 )
701
703
else :
702
704
value = f'0x{ value :08X} '
703
- if label :
704
- emit = f'{ label } .4byte { value } '
705
- else :
706
- emit = f'\t .4byte { value } '
705
+ emit = f'{ label } .4byte { value } ' if label else f'\t .4byte { value } '
707
706
if DEBUG :
708
707
comment += f' @ { addr_flags } '
709
708
f .write (f'{ emit } { comment } \n ' )
@@ -729,7 +728,7 @@ def warn(*args):
729
728
flags = addr_flags
730
729
addr += offset
731
730
bar .update (offset )
732
- # Close current module
731
+ # Done with output; close file handles and cleanup
733
732
if f is not sys .stdout and f :
734
733
if bytecount :
735
734
f .write ('\n ' )
0 commit comments