Загрузка данных
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()