From f93bb2f5dee8387dba77cc08a48fb79a6d94d0e5 Mon Sep 17 00:00:00 2001 From: rexim Date: Sat, 20 Jan 2024 17:54:26 +0700 Subject: [PATCH] =?UTF-8?q?=D0=A3=D1=81=D1=82=D1=80=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20=D0=BF=D1=80=D0=B5=D0=B4=D1=83=D0=BF=D1=80=D0=B5?= =?UTF-8?q?=D0=B6=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- исходники/хуяк.rs | 49 +++++++++++++++++++++++++++++++++++++++++++---- исходники/эльф.rs | 9 --------- собрать.sh | 1 - 3 files changed, 45 insertions(+), 14 deletions(-) diff --git a/исходники/хуяк.rs b/исходники/хуяк.rs index a02909d..ff956ba 100644 --- a/исходники/хуяк.rs +++ b/исходники/хуяк.rs @@ -258,17 +258,58 @@ const КОМАНДЫ: &[Команда] = &[ }, Команда { имя: "объект", - сигнатура: "<путь_к_файлу>", + сигнатура: " [-цель <цель>] <путь_к_файлу>", описание: "Сгенерировать объектный файл, который можно скомпоновать со статическими библиотеками.", запустить: |программа, mut аргы| { - let путь_к_файлу = if let Some(путь_к_файлу) = аргы.next() { - PathBuf::from(путь_к_файлу) + let mut файл_вывода = None; + let mut цель = Цель::ЛинуксИкс86_64Фазм; + + loop { + match аргы.next() { + Some(арг) => match арг.as_str() { + "-цель" => { + match аргы.next() { + Some(арг) => match арг.as_str() { + "эльф" => цель = Цель::ЛинуксИкс86_64Эльф, + "фазм" => цель = Цель::ЛинуксИкс86_64Фазм, + _ => { + eprintln!("ОШИБКА: неизвестная цель «{арг}»"); + // СДЕЛАТЬ: напечатать список возможных целей + return Err(()) + } + } + None => { + eprintln!("ОШИБКА: Флаг «{арг}» требует значение."); + return Err(()) + } + } + } + _ => { + if файл_вывода.is_some() { + пример(программа); + eprintln!("ОШИБКА: Неизвестный флаг «{арг}»."); + return Err(()) + } else { + файл_вывода = Some(арг) + } + } + } + None => break, + } + } + + let файл_вывода = if let Some(файл_вывода) = аргы.next() { + PathBuf::from(файл_вывода) } else { пример(программа); eprintln!("ОШИБКА: требуется путь к файлу!"); return Err(()); }; - фазм::сгенерировать_объектный_файл(&путь_к_файлу) + + match цель { + Цель::ЛинуксИкс86_64Фазм => фазм::сгенерировать_объектный_файл(&файл_вывода), + Цель::ЛинуксИкс86_64Эльф => эльф::сгенерировать_объектный_файл(&файл_вывода), + } } }, ]; diff --git a/исходники/эльф.rs b/исходники/эльф.rs index 9f91d50..6c9a11d 100644 --- a/исходники/эльф.rs +++ b/исходники/эльф.rs @@ -27,7 +27,6 @@ const ЭЛЬФ_ТЕКУЩАЯ_ВЕРСИЯ: usize = 1; // EV_CURRENT const ЭЛЬФ64_РАЗМЕР_ЭЛЬФ_ЗАГОЛОВКА: usize = 64; // sizeof(Elf64_Ehdr) const ЭЛЬФ64_РАЗМЕР_ПРОГ_ЗАГОЛОВКА: usize = 56; // sizeof(Elf64_Phdr) const ЭЛЬФ64_РАЗМЕР_СЕКЦ_ЗАГОЛОВКА: usize = 64; // sizeof(Elf64_Shdr) -const ЭЛЬФ64_РАЗМЕР_ЗАПИСИ_СИМВОЛА: usize = 24; // sizeof(Elf64_Sym) enum ЭльфТип { // e_type Перемещаемый = 1, // ET_REL @@ -328,11 +327,6 @@ pub fn сгенерировать_исполняемый_файл(путь_к_ф } } -fn выравнять_байты(байты: &mut Vec, выравнивание: usize) { - let новый_размер = (байты.len() + выравнивание - 1)/выравнивание*выравнивание; - байты.resize(новый_размер, 0); -} - #[derive(Clone, Copy)] enum ТипСекции { // sh_type Пустая = 0, // SHT_NULL @@ -406,14 +400,11 @@ impl Секция { #[derive(Clone, Copy)] enum ТипСимвола { Никакой = 0, // STT_NOTYPE - Функция = 2, // STT_FUNC - Секция = 3, // STT_SECTION } #[derive(Clone, Copy)] enum СвязьСимвола { Локальная = 0, // STB_LOCAL - Глобальная = 1, // STB_GLOBAL } fn символ_инфо(связь: СвязьСимвола, тип: ТипСимвола) -> u8 { // ELF64_ST_INFO(bind, type) diff --git a/собрать.sh b/собрать.sh index f162b2d..bf78786 100755 --- a/собрать.sh +++ b/собрать.sh @@ -6,7 +6,6 @@ mkdir -p ./сборка/ rustc -o ./сборка/хуяк -g исходники/хуяк.rs mkdir -p ./сборка/примеры/ - ./сборка/хуяк комп -цель фазм -вывод ./сборка/примеры/01-привет-фазм ./примеры/01-привет.хуя ./сборка/хуяк комп -цель фазм -вывод ./сборка/примеры/02-цикл-фазм ./примеры/02-цикл.хуя ./сборка/хуяк комп -цель фазм -вывод ./сборка/примеры/03-имя-фазм ./примеры/03-имя.хуя