From 28a3c04fbbe7a599b6d48cb693b9cfaec095cdb6 Mon Sep 17 00:00:00 2001 From: rexim Date: Sat, 20 Jan 2024 13:58:12 +0700 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D1=82?= =?UTF-8?q?=D1=8C=20=D0=BD=D0=B5=D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D1=87=D0=B5?= =?UTF-8?q?=D0=BD=D0=BD=D1=8B=D0=B5=20=D1=81=D0=B8=D0=BC=D0=B2=D0=BE=D0=BB?= =?UTF-8?q?=D1=8B=20=D0=B2=20=D0=B3=D0=B5=D0=BD=D0=B5=D1=80=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D1=8E=20=D1=8D=D0=BB=D1=8C=D1=84=20=D0=BE=D0=B1=D1=8A?= =?UTF-8?q?=D0=B5=D0=BA=D1=82=D0=B8=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- исходники/эльф.rs | 77 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 7 deletions(-) diff --git a/исходники/эльф.rs b/исходники/эльф.rs index b001e54..baecec4 100644 --- a/исходники/эльф.rs +++ b/исходники/эльф.rs @@ -18,14 +18,16 @@ const ЭЛЬФ64_МПБ_СИС5_ИДЕНТ: &[u8] = // e_ident type Эльф64Пол = u16; // Elf64_Half type Эльф64Слово = u32; // Elf64_Word -type Эльф64ХСлово = u64; // Elf64_XWord +type Эльф64Хслово = u64; // Elf64_Xword type Эльф64Адрес = u64; // Elf64_Addr type Эльф64Смещ = u64; // Elf64_Off +type Эльф64Секция = u16; // Elf64_Section 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 @@ -333,8 +335,9 @@ fn выравнять_байты(байты: &mut Vec, выравниван #[derive(Clone, Copy)] enum ТипСекции { // sh_type - Пустая = 0, // SHT_NULL - ТаблицаСтрок = 3, // SHT_STRTAB + Пустая = 0, // SHT_NULL + ТаблицаСимволов = 2, // SHT_SYMTAB + ТаблицаСтрок = 3, // SHT_STRTAB } struct Секция { @@ -354,6 +357,19 @@ impl Секция { } } + fn таблица_символов<'ы>(символы: &[Символ], смещения_строк: &HashMap<&'ы str, usize>) -> Секция { + let mut байты: Vec = Vec::new(); + for символ in символы { + байты.extend(символ.байты(смещения_строк)); + } + Секция { + имя: ".symtab", + тип: ТипСекции::ТаблицаСимволов, + байты, + выравнивание: 1, + } + } + fn таблица_строк<'ы>(строки: &[&'ы str]) -> (Секция, HashMap<&'ы str, usize>) { let mut байты: Vec = Vec::new(); let mut смещения_строк: HashMap<&str, usize> = HashMap::new(); @@ -375,14 +391,60 @@ impl Секция { let mut байты: Vec = Vec::new(); байты.extend((*смещения_строк.get(self.имя).unwrap() as Эльф64Слово).to_le_bytes()); // sh_name байты.extend((self.тип as Эльф64Слово).to_le_bytes()); // sh_type - байты.extend((0 as Эльф64ХСлово).to_le_bytes()); // sh_flags + байты.extend((0 as Эльф64Хслово).to_le_bytes()); // sh_flags байты.extend((0 as Эльф64Адрес).to_le_bytes()); // sh_addr байты.extend(начало_секции.to_le_bytes()); // sh_offset - байты.extend((self.байты.len() as Эльф64ХСлово).to_le_bytes()); // sh_size + байты.extend((self.байты.len() as Эльф64Хслово).to_le_bytes()); // sh_size байты.extend((0 as Эльф64Слово).to_le_bytes()); // sh_link байты.extend((0 as Эльф64Слово).to_le_bytes()); // sh_info - байты.extend((self.выравнивание as Эльф64ХСлово).to_le_bytes()); // sh_addralign - байты.extend((0 as Эльф64ХСлово).to_le_bytes()); // sh_entsize + байты.extend((self.выравнивание as Эльф64Хслово).to_le_bytes()); // sh_addralign + байты.extend((0 as Эльф64Хслово).to_le_bytes()); // sh_entsize + байты + } +} + +#[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) + ((связь as u8)<<4) + ((тип as u8)&0xF) +} + +struct Символ { + имя: &'static str, // st_name + тип: ТипСимвола, // st_info (st_type) + связь: СвязьСимвола, // st_info (st_bind) + индекс_секции: usize, // st_shndx +} + +impl Символ { + fn пустой() -> Символ { + Символ { + имя: "", + тип: ТипСимвола::Никакой, + связь: СвязьСимвола::Локальная, + индекс_секции: 0, + } + } + + fn байты<'ы>(&self, смещения_строк: &HashMap<&'ы str, usize>) -> Vec { + let mut байты = Vec::new(); + байты.extend((*смещения_строк.get(self.имя).unwrap() as Эльф64Слово).to_le_bytes()); // st_name + байты.extend(символ_инфо(self.связь, self.тип).to_le_bytes()); // st_info + байты.extend((0 as u8).to_le_bytes()); // st_other + байты.extend((self.индекс_секции as Эльф64Секция).to_le_bytes()); // st_shndx + байты.extend((0 as Эльф64Адрес).to_le_bytes()); // st_value + байты.extend((0 as Эльф64Хслово).to_le_bytes()); // st_size байты } } @@ -398,6 +460,7 @@ pub fn сгенерировать_объектный_файл(путь_к_фай ]); let индекс_таблицы_строк = секции.len(); секции.push(секция_таблицы_строк); + секции.push(Секция::таблица_символов(&[Символ::пустой()], &смещения_строк)); let mut байты: Vec = Vec::new(); байты.extend(ЭЛЬФ64_МПБ_СИС5_ИДЕНТ); // e_ident