# ==========================================
# Step 2: Build individual LMA and VMA adjustments
# ==========================================
dynamic_offsets = []
if os.path.exists(readelf_bin):
res = subprocess.run([readelf_bin, "-SW", elf_path], capture_output=True, text=True)
if res.returncode == 0:
section_regex = re.compile(r'^\s*\[\s*\d+\]\s+([\.\w\-_]+)\s+(\w+)\s+([0-9a-fA-F]{8,16})')
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 = match.groups()
if sec_name in [".comment", ".symtab", ".strtab", ".shstrtab"] or sec_name.startswith(".debug"):
continue
vma_val = int(vma_str, 16)
if sec_type == "NOBITS" or vma_val < 0x80000000:
continue
# КРИТИЧЕСКИЙ ФИКС ДЛЯ MPU И ДЕБАГА:
# Если секция из региона данных (0x80400000+)
if vma_val >= 0x80400000:
# Вычисляем новый адрес исполнения в RAM (VMA) строго встык за кодом
new_vma = current_flash_lma + 0x20000000
# Принудительно меняем и адрес во флеше (LMA), и адрес работы в ОЗУ (VMA)
dynamic_offsets += ["--change-section-lma", f"{sec_name}={hex(current_flash_lma)}"]
dynamic_offsets += ["--change-section-vma", f"{sec_name}={hex(new_vma)}"]
size_res = re.search(r'^\s*\[\s*\d+\]\s+' + re.escape(sec_name) + r'\s+\w+\s+[0-9a-fA-F]+\s+[0-9a-fA-F]+\s+([0-9a-fA-F]+)', res.stdout, re.M)
if size_res:
current_flash_lma += (int(size_res.group(1), 16) + 3) & ~3
else:
# Для секций кода оставляем стандартный сдвиг LMA на 0x60000000
standard_lma = vma_val - 0x20000000
dynamic_offsets += ["--change-section-lma", f"{sec_name}={hex(standard_lma)}"]