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


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)

    real_objcopy = sys.argv[1]
    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)
        offset = ""
        for arg in args:
            if arg.startswith("*+") or arg.startswith("*-"):
                offset = arg[1:] # Отсекаем звездочку
                break
        
        # 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

        # 3. Читаем структуру секций zephyr.elf
        res = subprocess.run([readelf_bin, "-S", "zephyr.elf"], capture_output=True, text=True)
        
        # 4. Ваша идея: отбираем секции, чей VMA-адрес строго начинается на '8'
        lma_args = []
        for line in res.stdout.splitlines():
            parts = line.split()
            # Пропускаем служебные заголовки readelf
            if len(parts) < 4 or "Адрес" in line or "Address" in line:
                continue
            
            # В зависимости от наличия индекса секции [ 1], имя и адрес могут смещаться.
            # Если строка начинается с [ или числа, parts[1] — имя, parts[2] — адрес.
            # Если строка — продолжение (редко), parts[0] — имя, parts[1] — адрес.
            try:
                if parts[0].startswith('[') or parts[0].isdigit():
                    sec_name = parts[1].replace('[', '').replace(']', '')
                    vma_addr = parts[2]
                else:
                    sec_name = parts[0]
                    vma_addr = parts[1]
                
                # Проверяем, что адрес начинается на 8 и это не bss/noinit
                if vma_addr.startswith('8'):
                    if "bss" not in sec_name and "noinit" not in sec_name:
                        lma_args.extend(["--change-section-lma", f"{sec_name}{offset}"])
            except IndexError:
                continue
        
        # 5. КОРРЕКТНАЯ ОЧИСТКА: Полностью удаляем старые флаги --change-section-lma и их параметры
        cleaned_args = []
        skip_next = False
        for arg in args:
            if skip_next:
                skip_next = False
                continue
            if arg == "--change-section-lma":
                skip_next = True # Пропускаем сам флаг и его следующее значение (*+...)
                continue
            if arg.startswith("!.dtcm"): # Убираем дефолтные исключения Zephyr
                continue
            cleaned_args.append(arg)
        
        # 6. Запускаем оригинальный objcopy только если нашли секции 0x8
        if lma_args:
            final_cmd = [real_objcopy] + lma_args + cleaned_args
            subprocess.run(final_cmd, check=True)
            print("[LMA Filter] Сдвиг LMA успешно применен только к секциям 0x8.")
        else:
            print("[LMA Filter] Предупреждение: Секции на 0x8 не найдены. Вызываем исходный objcopy.")
            subprocess.run([real_objcopy] + args, check=True)
    else:
        # Для всех остальных вызовов просто передаем управление оригиналу
        subprocess.run([real_objcopy] + args, check=True)

if __name__ == "__main__":
    main()