Загрузка данных


import sys
import subprocess
import os
import re

def main():
    if len(sys.argv) < 2:
        print("[LMA Filter] Error: No real objcopy path provided.")
        sys.exit(1)

    real_objcopy = sys.argv[1]
    args = sys.argv[2:]
    
    # Поиск пути к zephyr.elf
    elf_path = "zephyr.elf"
    for arg in args:
        if arg.endswith("zephyr.elf"):
            elf_path = arg
            break

    # Идентифицируем деструктивный ELF-to-ELF шаг (пропускаем его)
    is_elf_to_elf_adjust = any("--change-section-lma" in arg for arg in args) and ("zephyr.elf" in elf_path) and not any(fmt in " ".join(args) for fmt in ["ihex", "binary"])

    if is_elf_to_elf_adjust:
        sys.exit(0)

    # Идентифицируем шаг генерации HEX или BIN
    is_hex_or_bin_generation = any("--output-target=" in arg for arg in args) or any(fmt in " ".join(args) for fmt in ["ihex", "binary"])

    if is_hex_or_bin_generation:
        # Глобальный сдвиг всей карты памяти LMA на -0x20000000
        shift_value = 0x20000000
        global_offset = ["--change-addresses", f"-{hex(shift_value)}"]
        
        # 1. Запускаем сборку бинарника/hex с глобальным сдвигом
        final_cmd = [real_objcopy] + global_offset + args
        subprocess.run(final_cmd, check=True)
        
        # 2. Динамический поиск пути к readelf для вывода логов
        sdk_bin_dir = os.path.dirname(real_objcopy)
        readelf_bin = os.path.join(sdk_bin_dir, "arm-zephyr-eabi-readelf")
        if not os.path.exists(readelf_bin):
            for file in os.listdir(sdk_bin_dir):
                if file.endswith("readelf"):
                    readelf_bin = os.path.join(sdk_bin_dir, file)
                    break

        if os.path.exists(readelf_bin):
            # Читаем структуру оригинального ELF-файла
            res = subprocess.run([readelf_bin, "-SW", elf_path], capture_output=True, text=True)
            if res.returncode == 0:
                print(f"\n[LMA Filter] === FINAL MEMORY MAP FOR FLASH ===")
                print(f"{'Section Name':<28} | {'Original VMA':<12} | {'Resulting LMA (Flash)':<22}")
                print("-" * 72)
                
                section_regex = re.compile(r'^\s*\[\s*\d+\]\s+([\.\w\-_]+)\s+(\w+)\s+([0-9a-fA-F]{8,16})')
                
                for line in res.stdout.splitlines():
                    match = section_regex.match(line)
                    if not match:
                        continue
                        
                    sec_name, sec_type, vma_str = match.groups()
                    
                    # Пропускаем служебные секции без флагов ALLOC (которые не идут во Flash)
                    # NOBITS секции (типа bss) физически не пишутся во Flash, но покажем их для полноты картины
                    if sec_name in [".comment", ".symtab", ".strtab", ".shstrtab"] or sec_name.startswith(".debug"):
                        continue
                    
                    vma_val = int(vma_str, 16)
                    
                    # Математический расчет результирующего LMA после работы objcopy
                    # Флаг --change-addresses вычитает 0x20000000 из ВСЕХ LMA адресов.
                    # В вашей конфигурации исходный LMA равен VMA, поэтому:
                    resulting_lma = vma_val - shift_value
                    
                    # Если адрес ушел в минус в рамках 32-битной логики (например, секции на 0x0... или 0x2...)
                    if resulting_lma < 0:
                        resulting_lma &= 0xFFFFFFFF
                        
                    vma_formatted = f"0x{vma_val:08X}"
                    lma_formatted = f"0x{resulting_lma:08X}"
                    
                    # Добавим маркер, чтобы визуально выделить Flash диапазон 0x6...
                    marker = "-> OK (Flash)" if lma_formatted.startswith("0x6") else ""
                    if sec_type == "NOBITS":
                        marker = "[RAM-only / BSS]"
                        
                    print(f"{sec_name:<28} | {vma_formatted:<12} | {lma_formatted:<22} {marker}")
                print("=" * 72 + "\n")
        else:
            print("[LMA Filter] Applied global LMA shift, but readelf log helper could not find readelf binary.")
    else:
        subprocess.run([real_objcopy] + args, check=True)

if __name__ == "__main__":
    main()