рефакторинг первого прохода
This commit is contained in:
parent
171cb1af10
commit
05b4230058
109
kvs_pass1.py
109
kvs_pass1.py
|
|
@ -13,13 +13,17 @@
|
|||
|
||||
import sys
|
||||
import csv
|
||||
import struct # <--- НОВЫЙ ИМПОРТ
|
||||
|
||||
sys.path.insert(0, '.')
|
||||
from kvs_data import PAGE_SIZE,ALWAYS_STUB_INSTRUCTIONS, text_vaddr_base, align_up
|
||||
from kvs_data import (
|
||||
PAGE_SIZE, text_vaddr_base, align_up,
|
||||
ALWAYS_STUB_INSTRUCTIONS
|
||||
)
|
||||
from kvs_encoder import encode_instruction
|
||||
|
||||
# ========== ГЛОБАЛЬНОЕ СОСТОЯНИЕ ==========
|
||||
entries = [] # (segment, address, virt_addr, byte, target, source, label, cmd_with_values, calc_target, calc_byte)
|
||||
entries = []
|
||||
current_address = 0
|
||||
current_segment = '.header'
|
||||
last_segment = None
|
||||
|
|
@ -45,7 +49,6 @@ entry_point = "_start"
|
|||
relocations = []
|
||||
|
||||
|
||||
|
||||
def reset_state():
|
||||
global entries, current_address, current_segment, last_segment
|
||||
global text_buffer, data_buffer, bnd_size, vaddr_data, vaddr_bnd
|
||||
|
|
@ -107,14 +110,14 @@ def add_byte(value: int, source: str = "", target=None, labels_list=None):
|
|||
entries.append((
|
||||
show_segment if show_segment else "",
|
||||
current_address,
|
||||
f"0x{virt_addr:08x}", # виртуальный_адрес
|
||||
f"0x{byte_val:02x}", # байт (в виде hex-строки)
|
||||
f"0x{virt_addr:08x}",
|
||||
f"0x{byte_val:02x}",
|
||||
target if target else "",
|
||||
source,
|
||||
effective_labels,
|
||||
"", # команда_со_значениями (заполняется во втором проходе)
|
||||
"", # рассчитанный_уводящий_адрес
|
||||
f"0x{byte_val:02x}" # рассчитанный_байт (изначально = байт)
|
||||
"",
|
||||
"",
|
||||
f"0x{byte_val:02x}"
|
||||
))
|
||||
current_address += 1
|
||||
|
||||
|
|
@ -127,33 +130,33 @@ def add_bytes(values, source: str = "", target=None):
|
|||
add_byte(v, source if i == 0 else "", target if i == 0 else None)
|
||||
|
||||
|
||||
# ========== РЕФАКТОРИНГ: ИСПОЛЬЗУЕМ struct.pack ==========
|
||||
|
||||
def add_word16(value: int, source: str = "", target=None):
|
||||
add_bytes([
|
||||
(value >> 0) & 0xFF,
|
||||
(value >> 8) & 0xFF,
|
||||
], source, target)
|
||||
"""Добавляет 16-битное значение (little-endian)"""
|
||||
add_bytes(struct.pack('<H', value & 0xFFFF), source, target)
|
||||
|
||||
|
||||
def add_word32(value: int, source: str = "", target=None):
|
||||
add_bytes([
|
||||
(value >> 0) & 0xFF,
|
||||
(value >> 8) & 0xFF,
|
||||
(value >> 16) & 0xFF,
|
||||
(value >> 24) & 0xFF,
|
||||
], source, target)
|
||||
"""Добавляет 32-битное значение (little-endian)"""
|
||||
add_bytes(struct.pack('<I', value & 0xFFFFFFFF), source, target)
|
||||
|
||||
|
||||
def add_word64(value: int, source: str = "", target=None):
|
||||
add_bytes([
|
||||
(value >> 0) & 0xFF,
|
||||
(value >> 8) & 0xFF,
|
||||
(value >> 16) & 0xFF,
|
||||
(value >> 24) & 0xFF,
|
||||
(value >> 32) & 0xFF,
|
||||
(value >> 40) & 0xFF,
|
||||
(value >> 48) & 0xFF,
|
||||
(value >> 56) & 0xFF,
|
||||
], source, target)
|
||||
"""Добавляет 64-битное значение (little-endian)"""
|
||||
add_bytes(struct.pack('<Q', value & 0xFFFFFFFFFFFFFFFF), source, target)
|
||||
|
||||
|
||||
def add_dwords(values: list, source: str = "", target=None):
|
||||
"""Добавляет несколько 32-битных значений"""
|
||||
for val in values:
|
||||
add_word32(val, source, target)
|
||||
|
||||
|
||||
def add_qwords(values: list, source: str = "", target=None):
|
||||
"""Добавляет несколько 64-битных значений"""
|
||||
for val in values:
|
||||
add_word64(val, source, target)
|
||||
|
||||
|
||||
def align_to(alignment: int):
|
||||
|
|
@ -185,6 +188,8 @@ def unescape_string(s):
|
|||
|
||||
|
||||
def generate_elf_header():
|
||||
"""Генерирует заголовок ELF (64 байта)"""
|
||||
# ELF magic
|
||||
add_bytes([0x7F, 0x45, 0x4C, 0x46], "ELF magic")
|
||||
add_byte(2, "ELFCLASS64")
|
||||
add_byte(1, "ELFDATA2LSB")
|
||||
|
|
@ -192,15 +197,25 @@ def generate_elf_header():
|
|||
add_byte(0, "OS ABI")
|
||||
add_byte(0, "ABI version")
|
||||
add_bytes([0] * 7, "Padding")
|
||||
|
||||
# e_type, e_machine, e_version
|
||||
add_word16(2, "e_type = ET_EXEC")
|
||||
add_word16(62, "e_machine = EM_X86_64")
|
||||
add_word32(1, "e_version")
|
||||
|
||||
# e_entry (stub - будет заполнен позже)
|
||||
add_word64(0, "e_entry (stub)")
|
||||
|
||||
# e_phoff, e_shoff
|
||||
add_word64(64, "e_phoff")
|
||||
add_word64(0, "e_shoff = 0")
|
||||
|
||||
# e_flags, e_ehsize, e_phentsize
|
||||
add_word32(0, "e_flags")
|
||||
add_word16(64, "e_ehsize")
|
||||
add_word16(56, "e_phentsize")
|
||||
|
||||
# e_phnum, e_shentsize, e_shnum, e_shstrndx
|
||||
add_word16(2, "e_phnum = 2")
|
||||
add_word16(0, "e_shentsize = 0")
|
||||
add_word16(0, "e_shnum = 0")
|
||||
|
|
@ -208,22 +223,25 @@ def generate_elf_header():
|
|||
|
||||
|
||||
def generate_program_headers():
|
||||
"""Генерирует два программных заголовка (PT_LOAD)"""
|
||||
# === Первый заголовок: TEXT (RX) ===
|
||||
add_word32(1, "p_type = PT_LOAD")
|
||||
add_word32(5, "p_flags = RX")
|
||||
add_word64(0, "p_offset (text stub)")
|
||||
add_word64(0, "p_offset (text stub)") # будет заполнено позже
|
||||
add_word64(vaddr_text, "p_vaddr (text)")
|
||||
add_word64(vaddr_text, "p_paddr (text)")
|
||||
add_word64(0, "p_filesz (text stub)")
|
||||
add_word64(0, "p_memsz (text stub)")
|
||||
add_word64(0, "p_filesz (text stub)") # будет заполнено позже
|
||||
add_word64(0, "p_memsz (text stub)") # будет заполнено позже
|
||||
add_word64(PAGE_SIZE, "p_align")
|
||||
|
||||
# === Второй заголовок: DATA (RW) ===
|
||||
add_word32(1, "p_type = PT_LOAD")
|
||||
add_word32(6, "p_flags = RW")
|
||||
add_word64(0, "p_offset (data stub)")
|
||||
add_word64(0, "p_vaddr (data stub)")
|
||||
add_word64(0, "p_paddr (data stub)")
|
||||
add_word64(0, "p_filesz (data stub)")
|
||||
add_word64(0, "p_memsz (data stub)")
|
||||
add_word64(0, "p_offset (data stub)") # будет заполнено позже
|
||||
add_word64(0, "p_vaddr (data stub)") # будет заполнено позже
|
||||
add_word64(0, "p_paddr (data stub)") # будет заполнено позже
|
||||
add_word64(0, "p_filesz (data stub)") # будет заполнено позже
|
||||
add_word64(0, "p_memsz (data stub)") # будет заполнено позже
|
||||
add_word64(PAGE_SIZE, "p_align")
|
||||
|
||||
|
||||
|
|
@ -643,7 +661,8 @@ def finalize_headers():
|
|||
segment, addr, virt_addr, byte_str, target, source, label, cmd_with_values, calc_target, calc_byte = entries[i]
|
||||
|
||||
if 'e_entry (stub)' in source:
|
||||
new_bytes = [(entry_point_addr >> j*8) & 0xFF for j in range(8)]
|
||||
# Вставляем 8 байт (uint64_t)
|
||||
new_bytes = struct.pack('<Q', entry_point_addr)
|
||||
for j, nb in enumerate(new_bytes):
|
||||
virt = f"0x{entry_point_addr + j:08x}"
|
||||
byte_hex = f"0x{nb:02x}"
|
||||
|
|
@ -655,7 +674,7 @@ def finalize_headers():
|
|||
continue
|
||||
|
||||
elif 'p_offset (text stub)' in source:
|
||||
new_bytes = [(text_offset >> j*8) & 0xFF for j in range(8)]
|
||||
new_bytes = struct.pack('<Q', text_offset)
|
||||
for j, nb in enumerate(new_bytes):
|
||||
virt = f"0x{addr + j:08x}"
|
||||
byte_hex = f"0x{nb:02x}"
|
||||
|
|
@ -667,7 +686,7 @@ def finalize_headers():
|
|||
continue
|
||||
|
||||
elif 'p_filesz (text stub)' in source:
|
||||
new_bytes = [(text_filesz >> j*8) & 0xFF for j in range(8)]
|
||||
new_bytes = struct.pack('<Q', text_filesz)
|
||||
for j, nb in enumerate(new_bytes):
|
||||
virt = f"0x{addr + j:08x}"
|
||||
byte_hex = f"0x{nb:02x}"
|
||||
|
|
@ -679,7 +698,7 @@ def finalize_headers():
|
|||
continue
|
||||
|
||||
elif 'p_memsz (text stub)' in source:
|
||||
new_bytes = [(text_memsz >> j*8) & 0xFF for j in range(8)]
|
||||
new_bytes = struct.pack('<Q', text_memsz)
|
||||
for j, nb in enumerate(new_bytes):
|
||||
virt = f"0x{addr + j:08x}"
|
||||
byte_hex = f"0x{nb:02x}"
|
||||
|
|
@ -691,7 +710,7 @@ def finalize_headers():
|
|||
continue
|
||||
|
||||
elif 'p_offset (data stub)' in source:
|
||||
new_bytes = [(data_offset >> j*8) & 0xFF for j in range(8)]
|
||||
new_bytes = struct.pack('<Q', data_offset)
|
||||
for j, nb in enumerate(new_bytes):
|
||||
virt = f"0x{addr + j:08x}"
|
||||
byte_hex = f"0x{nb:02x}"
|
||||
|
|
@ -703,7 +722,7 @@ def finalize_headers():
|
|||
continue
|
||||
|
||||
elif 'p_vaddr (data stub)' in source:
|
||||
new_bytes = [(vaddr_data_final >> j*8) & 0xFF for j in range(8)]
|
||||
new_bytes = struct.pack('<Q', vaddr_data_final)
|
||||
for j, nb in enumerate(new_bytes):
|
||||
virt = f"0x{vaddr_data_final + j:08x}"
|
||||
byte_hex = f"0x{nb:02x}"
|
||||
|
|
@ -715,7 +734,7 @@ def finalize_headers():
|
|||
continue
|
||||
|
||||
elif 'p_paddr (data stub)' in source:
|
||||
new_bytes = [(vaddr_data_final >> j*8) & 0xFF for j in range(8)]
|
||||
new_bytes = struct.pack('<Q', vaddr_data_final)
|
||||
for j, nb in enumerate(new_bytes):
|
||||
virt = f"0x{vaddr_data_final + j:08x}"
|
||||
byte_hex = f"0x{nb:02x}"
|
||||
|
|
@ -727,7 +746,7 @@ def finalize_headers():
|
|||
continue
|
||||
|
||||
elif 'p_filesz (data stub)' in source:
|
||||
new_bytes = [(data_filesz >> j*8) & 0xFF for j in range(8)]
|
||||
new_bytes = struct.pack('<Q', data_filesz)
|
||||
for j, nb in enumerate(new_bytes):
|
||||
virt = f"0x{addr + j:08x}"
|
||||
byte_hex = f"0x{nb:02x}"
|
||||
|
|
@ -739,7 +758,7 @@ def finalize_headers():
|
|||
continue
|
||||
|
||||
elif 'p_memsz (data stub)' in source:
|
||||
new_bytes = [(data_memsz >> j*8) & 0xFF for j in range(8)]
|
||||
new_bytes = struct.pack('<Q', data_memsz)
|
||||
for j, nb in enumerate(new_bytes):
|
||||
virt = f"0x{addr + j:08x}"
|
||||
byte_hex = f"0x{nb:02x}"
|
||||
|
|
|
|||
Loading…
Reference in a new issue