# Step 2: Build individual LMA adjustments based on Flags, Type and VMA
dynamic_offsets = []
final_payload_end_lma = flash_data_start_lma
if os.path.exists(readelf_bin):
res = subprocess.run([readelf_bin, "-SW", elf_path], capture_output=True, text=True)
if res.returncode == 0:
# Регулярное выражение теперь захватывает: Имя, Тип, VMA, Смещение, Размер и Флаги
# Пример строки readelf: [ 1] text ALLOC LOAD ...
section_regex = re.compile(
r'^\s*\[\s*\d+\]\s+([\.\w\-_]+)\s+(\w+)\s+([0-9a-fA-F]{8,16})\s+[0-9a-fA-F]+\s+([0-9a-fA-F]+)\s+[0-9a-fA-F]+\s+([AXMSILG01-9\s]+)'
)
current_flash_lma = flash_data_start_lma
for line in res.stdout.splitlines():
match = section_regex.match(line)
if match:
sec_name, sec_type, vma_str, size_str, flags_str = match.groups()
vma_val = int(vma_str, 16)
size_val = int(size_str, 16)
# Проверяем, что секция требует выделения памяти (ALLOC -> содержит флаг 'A')
is_alloc = 'A' in flags_str
# Проверяем, что секция содержит физические данные (не NOBITS)
has_contents = (sec_type != "NOBITS") and (size_val > 0)
# Проверяем, относится ли VMA к физическому диапазону SDRAM (32MB)
is_in_sdram = (0x80000000 <= vma_val < 0x82000000)
# Если секция не в SDRAM, или не требует загрузки — полностью ИГНОРИРУЕМ её
if not (is_alloc and has_contents and is_in_sdram):
continue
# Логика деления на регион КОДА (0x80000000 - 0x803FFFFF) и ДАННЫХ (0x80400000+)
if vma_val >= 0x80400000:
# Данные последовательно упаковываем во Flash друг за другом
dynamic_offsets += ["--change-section-lma", f"{sec_name}={hex(current_flash_lma)}"]
current_flash_lma += (size_val + 3) & ~3
final_payload_end_lma = current_flash_lma
else:
# Код стандартно сдвигаем на физический адрес FlexSPI Flash (-0x20000000)
standard_lma = vma_val - 0x20000000
dynamic_offsets += ["--change-section-lma", f"{sec_name}={hex(standard_lma)}"]