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


import sys
import subprocess
import os

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

    # Забираем путь к настоящему objcopy, который нам передал CMake
    real_objcopy = sys.argv[1]
    
    # Все остальные аргументы — это то, что передал Zephyr для objcopy
    args = sys.argv[2:]
    
    # Проверяем, является ли этот вызов деструктивным сдвигом LMA со звездочкой '*'
    is_lma_adjust = any("--change-section-lma" in arg for arg in args) and any("*" in arg for arg in args)
    
    if is_lma_adjust:
        print("[LMA Filter] Перехват деструктивного сдвига LMA...")
        
        # 1. Извлекаем величину смещения (например, +3758096384 или +-536870912)
        offset = ""
        for arg in args:
            if arg.startswith("*+") or arg.startswith("*-"):
                offset = arg[1:] # Отсекаем звездочку
                break
        
        # 2. Вычисляем путь к readelf, так как он всегда лежит в одной папке с objcopy
        sdk_bin_dir = os.path.dirname(real_objcopy)
        readelf_bin = os.path.join(sdk_bin_dir, "arm-zephyr-eabi-readelf")
        
        # На всякий случай: если префикс тулчейна отличается, ищем любой 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

        # 3. Парсим структуру zephyr.elf
        res = subprocess.run([readelf_bin, "-S", "zephyr.elf"], capture_output=True, text=True)
        
        # 4. Ваша идея: отбираем секции, чей VMA-адрес (3-я колонка) строго начинается на '8'
        lma_args = []
        for line in res.stdout.splitlines():
            parts = line.split()
            if len(parts) >= 4 and parts[2].startswith("8"):
                sec_name = parts[1].replace("[", "").replace("]", "")
                # Секции без данных (NOBITS) во FLASH не копируются
                if "bss" not in sec_name and "noinit" not in sec_name:
                    lma_args.extend(["--change-section-lma", f"{sec_name}{offset}"])
        
        # 5. Вырезаем из исходной команды Zephyr маску '*' и дефолтные исключения, которые мешают
        cleaned_args = [arg for arg in args if not (arg.startswith("*+") or arg.startswith("*-") or arg.startswith("!--change-section-lma"))]
        cleaned_args = [arg for arg in cleaned_args if not arg.startswith("!.dtcm")]
        
        # 6. Запускаем оригинальный objcopy точечно и безопасно
        final_cmd = [real_objcopy] + lma_args + cleaned_args
        subprocess.run(final_cmd, check=True)
        print("[LMA Filter] Сдвиг LMA успешно применен только к секциям 0x8.")
    else:
        # Для всех остальных вызовов (генерация ihex, binary, удаление .comment) просто передаем управление
        subprocess.run([real_objcopy] + args, check=True)

if __name__ == "__main__":
    main()